powershell批处理——io校验

powershell批处理------io校验

在刷题时,时常回想,OJ平台是如何校验竞赛队员提交的代码的,OJ平台并不看代码,而是使用"黑盒测试",用测试数据来验证。对于每题,都事先设定了很多组输入数据(datain)和输出数据(dataout),OJ主要是看输入datain,看产生的输出是否与dataout一致。

如果需要一次性知道自己的所有测试输入数据是否能得到正确输出,一个一个测试就太慢了,批处理操作就能很好解决这个问题。本篇文章主要介绍一下这个ioCode小项目,主要用于批处理校验输入输出,搭建本地的评测平台。

项目目录结构

  1. input目录:存放输入数据文件,以.in后缀结尾
  2. output目录:存放输出数据文件,以.out后缀结尾,每个输出的文件名与对应的输入的文件名相同
  3. start.ps1:编写的脚本文件

start.ps1源代码:

powershell 复制代码
function ioCheck{
    param(
        $content, #程序输出内容
        $answer #输出的答案内容
    )
    $cnt = $answer.length
    if($content.length -ne $cnt){
        return 0  #内容行数不等,直接返回0
    }
    for($i=0;$i -lt $cnt;$i++){
        if($answer[$i] -ne $content[$i]){
            return 0
        } 
    }
    return 1
}

function ioCode{
    param(
		[string]$command,
        [string]$inPath = './input',
        [string]$outPath = './output'
    )
    $list = New-Object System.Collections.ArrayList  #创建正确输出的文件名集合
    $inFiles = Get-ChildItem -Path $inPath -Filter *.in  #获取输入文件集
    $len = $inFiles.length
    $cnt = 0 
    foreach($file in $inFiles){
        try {
            $fullOut = cmd.exe /c "$command < $($file.fullName)"  #获取程序实际输出内容
            $answerPath = Join-Path -Path $outPath -ChildPath ($file.BaseName + '.out')
            $answer = Get-Content -Path $answerPath  #获取该输入文件的对应输出文件的内容
            if(ioCheck $fullOut $answer){
                $list.add($file.Name) | Out-Null  #Out-Null表示丢弃输出
                $cnt++
            }
        }
        catch {
            Write-Host "处理文件 $($file.Name) 时出现错误: $_"
        }
    }
    Write-Host "正确输出 $cnt/$len:"

    return @{
        CorrectCount = $cnt
        TotalCount = $len
        CorrectFiles = $list
    }
}

首先测试输入两个数,看能否成功输出两数之和

在input目录中创建三个文件分别为001.in,002.in,003.in

内容分别为

001.in

复制代码
3 4

002.in

复制代码
35749 47985

003.in

复制代码
544 6755

对应的在output目录创建三个同名的.out文件,分别为001.out002.out003.out

内容就是对应.in文件中两个输入数据的相加的结果。

使用

编写好测试用例,就是可以测试我们写好的代码了,这里不仅可以测试C/C++生成的.exe可执行文件,还可以测试java生成的.class可执行字节码文件(前提是电脑具备java环境)。

测试.exe文件

在当前目录下准备一个test.cpp文件,代码如下:

cpp 复制代码
#include<iostream>
using namespace std;
int main()
{
    int a, b;
    cin >> a >> b;
    cout <<a<<"+"<<b <<"=" << a + b;
    return 0;
}

将其编译为可执行文件test.exe

bash 复制代码
g++ -o test.exe test.cpp

在当前目录下打开powershell控制台

  1. 通过点加载start.ps1文件
powershell 复制代码
. './start.ps1'
  1. 输入命令ioCode {command} {inPath} {outPath},command为可执行命令,inPath为输入文件目录(默认为当前目录的input目录),outPath为输出答案文件目录(默认为当前目录的output目录)
bash 复制代码
ioCode test.exe

示例:

控制台输出显示我们的三个测试用例都通过了。

测试可执行.class文件

在当前目录下准备一个Main.java文件,代码如下:

java 复制代码
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int a = scanner.nextInt();
        int b = scanner.nextInt();
        System.out.println(a+b);
    }
}

将其编译为可执行文件Main.class

pwershell 复制代码
javac Main.java

将其编译为可执行文件test.exe

powershell 复制代码
g++ -o test.exe test.cpp

在当前目录下打开powershell控制台

  1. 通过点加载start.ps1文件
powershell 复制代码
. './start.ps1'
  1. 输入命令ioCode {command} {inPath} {outPath},command为可执行命令,inPath为输入文件目录(默认为当前目录的input目录),outPath为输出答案文件目录(默认为当前目录的output目录)
bash 复制代码
ioCode 'java Main'  #注意java Main是一个完整的命令,中间带有空格,需要用引号引起来

示例:

以上就是这个小项目的内容,通过ioCode可以批处理测试多个输入输出用例,并能清晰的看到哪些输入文件正确输出方便DeBug。

后面我打算继续优化一下,主要包括以下内容

  1. 快速构造输入,输出数据。
  2. 对于不正确的输出(与给定的输出文件不匹配),能清晰地指出出第一个不同的地方。
  3. 显示批处理执行耗时

更多优化点或不足的地方,期待指教。

相关推荐
灰色人生qwer16 小时前
使用JMeter 编写的测试计划的多个线程组如何生成独立的线程组报告
jmeter·测试
试着1 天前
【AI面试准备】TensorFlow与PyTorch构建缺陷预测模型
人工智能·pytorch·面试·tensorflow·测试
waves浪游2 天前
博客系统测试报告
测试工具·测试用例·bug·测试
智云软件测评服务3 天前
数字化时代下,软件测试中的渗透测试是如何保障安全的?
渗透·测试·漏洞
试着4 天前
【AI面试准备】XMind拆解业务场景识别AI赋能点
人工智能·面试·测试·xmind
蓝黑20204 天前
PowerShell从5.1升级到7.X
windows·powershell
waves浪游6 天前
性能测试工具篇
测试工具·测试用例·bug·测试
艾策第三方软件测评8 天前
软件产品测试报告:如何全面评估及保障软件质量?
测试·软件·评估
转转技术团队12 天前
告别人工搬运!TiDB/MySQL双库同步工具如何为业务提效100%?
mysql·tidb·测试