あなたの説明から、Windows の何かがテスト アプリケーションの正常な動作を妨げているように思えます。2 番目のユーザーが問題になる可能性があるのは事実かもしれませんが、Windows XP での動作に関する明確な説明を見つけることができなかったため、確認できません。アーキテクチャの変更により、これが Windows Vista、7、8、またはサーバー マシンでは機能しないことは確かです。
自動化された UI テストがインタラクティブなユーザーによって開始されるようにすることが最善の解決策のように思えます。ビルドに自動テストを追加しようとしたとき、Windows XP SP2 仮想マシンで TestComplete 7 を使用しました。インタラクティブなユーザーとしてテストを開始するには、次のことを行います。
- Windows の起動時にユーザー ログオンを作成しました。このようにして、対話型のユーザーが常に存在しました。つまり、キーボード/マウスにアクセスできる実際のデスクトップ セッションがあったことを意味します。インタラクティブなユーザーがいなければ、キーボード/マウスにアクセスできるアクティブなデスクトップがないことを覚えているようです(ただし、現時点ではリンクが見つかりません)。
インタラクティブなユーザーがログオンしたときに起動する小さなアプリを作成しました。このアプリは特定のファイルを調べ、そのファイルが変更または作成されると、ファイルを読み取ってアプリケーションを起動します。このアプリのコードは次のようになります。
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ApplicationStarter
{
class Program
{
// The string used to indicate that the application should quit.
private const string ExitString = "exit";
// The path which is being watched for changes.
private static string s_LoadFilePath;
static void Main(string[] args)
{
try
{
{
Debug.Assert(
args != null,
"The arguments array should not be null.");
Debug.Assert(
args.Length == 1,
"There should only be one argument.");
}
s_LoadFilePath = args[0];
{
Console.WriteLine(
string.Format(
CultureInfo.InvariantCulture,
"Watching: {0}",
s_LoadFilePath));
}
if (File.Exists(s_LoadFilePath))
{
RunApplication(s_LoadFilePath);
}
using (var watcher = new FileSystemWatcher())
{
watcher.IncludeSubdirectories = false;
watcher.NotifyFilter =
NotifyFilters.LastAccess
| NotifyFilters.LastWrite
| NotifyFilters.FileName
| NotifyFilters.DirectoryName;
watcher.Path = Path.GetDirectoryName(s_LoadFilePath);
watcher.Filter = Path.GetFileName(s_LoadFilePath);
try
{
watcher.Created += OnConfigFileCreate;
watcher.EnableRaisingEvents = true;
// Now just sit here and wait until hell freezes over
// or until the user tells us that it has
string line = string.Empty;
while (!string.Equals(line, ExitString, StringComparison.OrdinalIgnoreCase))
{
line = Console.ReadLine();
}
}
finally
{
watcher.Created -= OnConfigFileCreate;
}
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
private static void RunApplication(string configFilePath)
{
var appPath = string.Empty;
var arguments = string.Empty;
using (var reader = new StreamReader(configFilePath, Encoding.UTF8))
{
appPath = reader.ReadLine();
arguments = reader.ReadLine();
}
// Run the application
StartProcess(appPath, arguments);
}
private static void StartProcess(string path, string arguments)
{
var startInfo = new ProcessStartInfo();
{
startInfo.FileName = path;
startInfo.Arguments = arguments;
startInfo.ErrorDialog = false;
startInfo.UseShellExecute = true;
startInfo.RedirectStandardOutput = false;
startInfo.RedirectStandardError = false;
}
Console.WriteLine(
string.Format(
CultureInfo.InvariantCulture,
"{0} Starting process {1}",
DateTime.Now,
path));
using (var exec = new Process())
{
exec.StartInfo = startInfo;
exec.Start();
}
}
private static void OnConfigFileCreate(
object sender,
FileSystemEventArgs e)
{
Console.WriteLine(
string.Format(
CultureInfo.InvariantCulture,
"{0} File change event ({1}) for: {2}",
DateTime.Now,
e.ChangeType,
e.FullPath));
// See that the file is there. If so then start the app
if (File.Exists(e.FullPath) &&
string.Equals(s_LoadFilePath, e.FullPath, StringComparison.OrdinalIgnoreCase))
{
// Wait for a bit so that the file is no
// longer locked by other processes
Thread.Sleep(500);
// Now run the application
RunApplication(e.FullPath);
}
}
}
}
このアプリは、ファイルに 2 つの行があることを想定しています。1 行目は開始するアプリで、2 行目は引数で、この場合は次のようになります。
C:\Program Files\Automated QA\TestComplete 7\Bin\TestComplete.exe
"D:\Test Complete7 Projects\ProjectInput_AllSamples\ProjecInputs.pjs" /r /p:Samples /rt:Main "iexplore" /e
ビルドステップで Jenkins からこのファイルを生成できるはずです。
最後に、終了時に TestComplete プロセスを監視して、最後に結果を取得できるようにする必要があるかもしれませんが、それは演習として読者に任せます。