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. 显示批处理执行耗时

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

相关推荐
北京_宏哥1 天前
《刚刚问世》系列初窥篇-Java+Playwright自动化测试-30- 操作单选和多选按钮 - 番外篇(详细教程)
java·前端·测试
Apifox1 天前
Apifox 7 月更新|通过 AI 命名参数及检测接口规范、在线文档支持自定义 CSS 和 JavaScript、鉴权能力升级
前端·后端·测试
前端工作日常3 天前
我学习到的描述项目持续迭代具体成果
前端·测试
前端工作日常5 天前
平台价值与用户规模的共生关系
electron·测试·puppeteer
CrissChan7 天前
AI赋能软件工程让测试左移更加可实施
人工智能·python·llm·软件工程·测试
努力奋斗的Tom8 天前
Air test框架与appium的优势
测试
瑞士龙珠9 天前
JMeter 多台压力机分布式测试(Windows)
测试
Apifox9 天前
如何在 Apifox 中正确使用前置 URL?
前端·后端·测试
陈哥聊测试10 天前
软件工程3.0时代,为什么人工测试仍必不可少?
人工智能·测试
檀檀199311 天前
测试抓包工具2-whistle抓包
测试