测试C#能否实现一个功能:运行指定的python代码,并自动用指定的输入进行测试,检查输出是否为预期结果。类似力扣、洛谷那样。但目的只是检查自家小孩写的程序是否通过而已。
窗口拉上三个文本框,一个按钮,就足够了。
代码如下:
private void button1_Click(object sender, EventArgs e)
{
string sFile = @"d:\1.py";
if (JLWJ(sFile, this.textBox1.Text) == false)
{
return;
}
Process oPro = new Process();
//pro.StartInfo.FileName = @"C:\Users\Administrator\AppData\Local\Programs\Python\Python37\python.exe";
oPro.StartInfo.FileName = @"py";
oPro.StartInfo.Arguments = @"d:\1.py";
oPro.StartInfo.UseShellExecute = false;
// 如果这个设为 false,就会出现:RuntimeError: input(): lost sys.stdin
// 所以一定要设为 true
oPro.StartInfo.RedirectStandardInput = true;
// 输出也用程序获取,所以设为 true
oPro.StartInfo.RedirectStandardOutput = true;
// 错误也用程序获取,所以设为 true
oPro.StartInfo.RedirectStandardError = true;
// 是否不要显示窗口(不显示比较清静,但看不到执行过程,有点不爽)
oPro.StartInfo.CreateNoWindow = true;
oPro.Start();
// 内容可以一次性输入完成,程序中计算延时会自动处理
oPro.StandardInput.WriteLine(this.textBox2.Text.Replace("@@", "\r\n"));
// 这个位置要在 Output.ReadToEnd 之前
oPro.WaitForExit();
// 程序中有打印输出的结果都在这里,不会区分答案与非答案(如输入提示信息),
// 所以程序中,只能输出规定格式的答案
string sRet = oPro.StandardOutput.ReadToEnd();
string sErr = "错误:" + oPro.StandardError.ReadToEnd();
// 自动补全回车
if (sRet == (this.textBox3.Text + "@@").Replace("@@", "\r\n"))
{
sRet = "成功!";
}
else
{
sRet = "失败!\r\n" +
"期待:" + this.textBox3.Text + "\r\n" +
"实际:" + sRet + "\r\n" +
sErr;
}
MessageBox.Show(sRet);
}
#region JLWJ - 建立文件
/// <summary>
/// 建立文件
/// 目录会自己建立, 已有文件将会被覆盖
/// </summary>
/// <param name="sFullFileName">要建立的文件的 完整名称</param>
/// <param name="sNR">要填充的文本内容, 普通字符串</param>
/// <returns>如果建立成功, 返回真, 否则返回假</returns>
public static bool JLWJ(string sFullFileName, string sNR)
{
string sPath = Path.GetDirectoryName(sFullFileName);
if (Directory.Exists(sPath) == false)
{
Directory.CreateDirectory(sPath);
}
StreamWriter oSW = File.CreateText(sFullFileName);
oSW.Write(sNR);
oSW.Flush();
oSW.Close();
bool bRet = File.Exists(sFullFileName);
return bRet;
}
#endregion
测试结果:
实际使用中是把这段代码与数据库里的题库、测试用例结合起来完成自己需要的功能。