为多个Python文件编写单元测试

为多个Python文件编写单元测试,python,python-3.x,unit-testing,argparse,Python,Python 3.x,Unit Testing,Argparse,我正试图编写一个测试程序来测试许多(相同的)学生作业。我有一个测试是用。文档似乎表明每个测试都应该与一个文件关联。相反,我希望有一个测试文件,并使用命令行参数将测试指向它应该测试的文件 我知道我可以通过在单元测试中使用模块来实现这一点,但是有更好的方法吗?看起来unittest中应该支持这种行为,但我在文档中找不到任何内容…创建主测试目录并添加子测试包。为您创建一个指向测试目录的测试运行程序。它可以作为一个套房。我附加了一段代码,用于我的测试套件 import os import unittes

我正试图编写一个测试程序来测试许多(相同的)学生作业。我有一个测试是用。文档似乎表明每个测试都应该与一个文件关联。相反,我希望有一个测试文件,并使用命令行参数将测试指向它应该测试的文件


我知道我可以通过在单元测试中使用模块来实现这一点,但是有更好的方法吗?看起来unittest中应该支持这种行为,但我在文档中找不到任何内容…

创建主测试目录并添加子测试包。为您创建一个指向测试目录的测试运行程序。它可以作为一个套房。我附加了一段代码,用于我的测试套件

import os
import unittest

def main(test_path, test_pattern):
    print(('Discovering tests in : {}'.format(test_path)))
    suite = unittest.TestLoader().discover(test_path, test_pattern)
    unittest.TextTestRunner(verbosity=2).run(suite)

if __name__ == '__main__':
    root_path = os.path.abspath('.')
    test_path = os.path.join(root_path, 'src/tests/')
    test_pattern = 'test_*'
    main(test_path, test_pattern)


一般来说,unittest用于测试模块级python代码,而不是python代码与外部程序的交互。另外,写入标准输出(即打印)意味着您正在调试或将信息传递给另一个程序

在您的情况下,我认为unittest并不是真正必要的,除非您希望分配“通过此unittest”的作业(这在野外很常见)

相反,我只需迭代包含分配的目录,使用子流程检查标准输出,然后将结果写入csv文件:

import subprocess
import os
import csv

ASSIGNMENT_DIR = '/path/to/assignments'

expected_stdout = 'Hello World!'

def _determine_grade(stdout):
    if stdout == expected_stdout:
        return '100%'
    return '0%'  

grades = {}   

for assignment in os.listdir(ASSIGNMENT_DIR):
    filepath = os.path.join(ASSIGNMENT_DIR, assignment)

    stdout = subprocesss.check_output(f'python3 {filepath}', shell=True)

    grade = _determine_grade(stdout)
    grades.append({'assignment':assignment, 'grade':grade})

with open('/path/to/grades.csv', 'w+') as f:
    w = csv.DictWriter(f, ('assignment', 'grade'))
    w.writeheader()
    w.writerows(grades)

作业的要求是什么?我的答案取决于你要准确测试的内容。作业要求学生从stdin获取输入(str),进行一些计算,然后将适当的值(str)返回到stdout。我设计的测试将给定的文件(当前为硬编码)作为子进程运行,并使用subprocess.communicate执行IPC(进程间通信)。谢谢,我今天晚些时候会尝试一下。这也可以很容易地规范化,以处理任何分配,如果您愿意,我可以向您展示。谢谢您的回答。我同意这样做很好。我决定使用unittest的原因是,学生的代码可能在某些情况下有效,而在其他情况下无效。因此,我有几个测试用例在每个任务上运行,每个测试用例检查不同类型的错误。一旦定义了测试用例,unittest就会自动运行它们,并以一种格式良好的方式报告每个测试的结果,这是我不必编写的许多样板文件。在未来,我想给我的学生们的测试运行自己添加一种“现实主义”的感觉。