2

jenkins からの呼び出し時に testcomplete で自動化されたプロジェクトを実行できません。

継続的インテグレーションの部分では、プロジェクトは testcomplete を使用して自動化されており、bat ファイルを使用して jenkins を呼び出しています。bat ファイル内のスクリプトは次のとおりです。

"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

testcomplete と iexplorer を開きますが、データを入力していません (自動化)。ジェンキンスを使用せずにバットファイルを直接呼び出すと、完全に機能します。解決策はありますか

4

2 に答える 2

1

Jenkins (マスターまたはスレーブ) を Windows サービスとして実行している場合は、ローカル システムとしてではなく、ユーザーとして実行されていることを確認してください。

また、Gentlesea の推奨と同じことを行います。Jenkins スレーブで TestExecute を実行し、TestComplete スクリプトを設計する人々のために TestComplete ライセンスを維持します。

于 2013-03-04T01:25:01.137 に答える
1

あなたの説明から、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 プロセスを監視して、最後に結果を取得できるようにする必要があるかもしれませんが、それは演習として読者に任せます。

于 2013-03-05T20:43:22.110 に答える