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

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

相关推荐
智擎软件测评小祺3 天前
渗透测试报告关键模块拆解
网络·web安全·渗透测试·测试·检测·cma·cnas
智擎软件测评小祺3 天前
渗透测试报告撰写:漏洞发现到验证流程
网络·渗透测试·测试·cma·第三方检测·cnas·渗透测试报告
jaycyj3 天前
Web端抓包工具操作与应用
测试
神秘的t5 天前
抽奖系统测试报告
测试
阳光普照世界和平5 天前
单元测试工具现状及实现思路探析
测试·软件质量
jaycyj5 天前
Web项目功能测试用例实战
测试
智擎软件测评小祺5 天前
从报告看懂安全隐患,提升防护能力
安全·web安全·渗透测试·测试·检测·cma·cnas
LAM LAB6 天前
【shell】win10 Powershell字体美化
powershell
独断万古他化7 天前
AI 赋能自动化测试实战:从用例生成到 CI/CD 全流程落地
人工智能·ci/cd·测试
甜甜圈圈子7 天前
基于Dify与DeepSeek:零门槛训练自己的专属AI大模型
测试