关于此主题的上一篇文章很有帮助(请参阅How to export TestExecute/TestComplete results to teamcity?)
现在,我们的TestComplete解决方案创建了一个文本文件,MSBuild使用Microsoft.Build.Utilities.Task帮助程序将该消息发送回TeamCity。但是,我想知道我们是否可以做得更好。
TeamCity帮助主题(http://confluence.jetbrains.com/display/TCD65/Build+Script+Interaction+with+TeamCity#BuildScriptInteractionwithTeamCity-ServiceMessages)说,消息“应该打印到构建的标准输出流”。我想弄清楚的是,我可以直接从TestComplete脚本访问该流吗?
我希望它会像以下一样简单: dotNET.System.Console.WriteLine_11(“## teamCity [testSuiteStarted name ='Foo']”);
但这显然没有给我正确的输出流。思考?可以吗?
答案 0 :(得分:1)
您遇到的问题是TestComplete不支持写入标准输出流,即使您调用CLR Console.WriteLine
,也要写入名为tcHostingProcess.exe的进程,其中存在所有CLR对象。
要解决此问题,您需要运行一个可以接受来自TestComplete项目的消息的控制台应用程序。有很多方法可以做到这一点,但这里提出的解决方案是使用TCP / IP进行必要的IPC。
在TeamCity中
在TeamCity构建步骤中,您希望TestComplete或TestExecute进程在不占用构建脚本的情况下启动,然后启动将从TestComplete接收消息的自定义控制台应用程序。
start TestComplete.exe [arg1] [arg2] ...
TCConsoleHost.exe
控制台主机应用
控制台宿主程序将启动TcpListener
,一旦客户端连接,它将从生成的NetworkStream
对象中读取消息并将其打印到控制台。该程序将继续,直到从流中读取错误(即TestComplete已退出)。
class Program
{
static void Main(string[] args)
{
TcpListener listener = new TcpListener(IPAddress.Parse("127.0.0.1"), 9800);
listener.Start();
TcpClient client = listener.AcceptTcpClient();
NetworkStream stream = client.GetStream();
BinaryReader reader = new BinaryReader(stream);
while (true)
{
try
{
string message = reader.ReadString();
Console.WriteLine(message);
}
catch
{
break;
}
}
}
}
消息客户端类
同样,我们可以创建一个TcpClient
,它可以连接到我们的监听过程并转发消息。这里真正的技巧是将它包装在一个带有静态构造函数的静态类中,这样一旦TestComplete加载CLR桥,它就会自动连接并准备发送消息。此示例具有TeamCity服务消息函数SendMessage
,它自动格式化消息(包括转义单引号)。
public static class TCServiceMessageClient
{
static BinaryWriter writer;
static NetworkStream stream;
static TCServiceMessageClient()
{
TcpClient client = new TcpClient();
client.Connect("127.0.0.1", 9800);
stream = client.GetStream();
writer = new BinaryWriter(stream);
}
public static void SendMessage(string message)
{
writer.Write(string.Format("##teamcity[message text='{0}'", message.Replace("'","|'")));
}
}
在TestComplete中
现在,由于客户端将在加载CLR桥时自动连接,因此TestComplete中唯一必需的代码是:
dotNET["TCServiceMessageClient"]["TCServiceMessageClient"]["SendMessage"]("Hello TeamCity!");
附加说明
上面的代码有一些注意事项,即计时,重新连接等。部署的解决方案应该有更好的网络条件错误处理。此外,可能更希望TCMessageHost应用程序实际上直接使用System.Process
对象启动TestComplete,以便它可以更可靠地等待应用程序退出。
答案 1 :(得分:0)
我也在使用TeamCity和TestComplete。我遇到了完全相同的问题,无论你怎么做,都无法写入控制台,至少不是我发现的。我甚至尝试编写一个C#应用程序,我在TestComplete中使用CLR桥来与它交谈,但仍然没有。
我们最终做的是创建处理TestExecute调用的批处理文件。然后我们从TeamCity调用批处理文件。要调用TestExecute,请使用此命令(使用您的pjs文件和/ p特定于您的测试):
start /wait TestExecute "{TestCaseID}.pjs" /r /e /p:"{TestCaseID}" /silentmode /forceconversion
然后我们检查TestExecute返回的ERRORLEVEL属性。级别2表示测试执行失败。在这种情况下,我们使用echo语句打印以下内容:
##teamcity[testFailed name='{TestCaseID} - {TestName}' message='TestExecute reported a failure' details='See artifacts']
TestExecute关闭后,它将尝试打开日志文件。我们设置了构建服务器,以便计算器打开mht文件,因为它们需要一段时间才能打开(在Windows右键单击 - >打开方式菜单中将其设置为默认值)。因此,在TestExecute完成后,它会打开计算器,然后我们的批处理文件会使用taskkill杀死计算器。
然后,我们将结果文件从TestExecute复制到指定位置(这是我们编写的单独可执行文件)。我们完成测试执行并将我们的工件发布到TestExecute:
echo ##teamcity[testFinished name='{TestCaseID} - {TestName}' duration='%milliSecondsElapsed%']
echo ##teamcity[publishArtifacts 'C:\BuildResults\{GroupName}\{TestCaseID}\*.mht']
有一点需要注意:我们从来没有能够让TestExecute一次可靠地运行单个测试,所以我们实际上使用了一个测试用例列表来为每个测试用例生成单独的pjs和mds文件。然后我们在TestExecute中使用那些生成的pjs和mds文件。这就是上面的{GroupName},{TestCaseID}和{TestName}变量来自的地方。这些是我们实施的具体内容,但您可能需要不同的指标。
希望这有帮助!
答案 2 :(得分:0)
如果您使用的是TestExecute,则最近它变得相对“简单”
使用以下参数执行TestExecute:
/exportlog:"log\Index.html" /SilentMode /DoNotShowLog
要完整了解TestExecute参数,请检查:https://support.smartbear.com/testexecute/docs/running/automating/command-line/command-line.html
使用构建级别报告设置您的TestComplete项目:
请注意,它区分大小写
在构建配置的“常规设置”选项卡中,将生成的日志文件夹导出为工件。
构建已运行后,您将可以看到TeamCity中嵌入的测试日志:
这是使用TestComplete V14和TeamCity 2019.1