您遇到的问题是 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("'","|'")));
}
}
在测试完成中
现在,由于客户端会在加载 CLR 网桥时自动连接,因此 TestComplete 中唯一需要的代码是:
dotNET["TCServiceMessageClient"]["TCServiceMessageClient"]["SendMessage"]("Hello TeamCity!");
补充说明
上面的代码有一些注意事项,即计时、重新连接等。部署的解决方案应该对网络条件有更好的错误处理。此外,可能更希望 TCMessageHost 应用程序实际使用System.Process
对象直接启动 TestComplete,以便它可以更可靠地等待应用程序退出。