You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python单元测试异常:自动评分器仅执行1个测试用例求助

问题原因与解决方案

你的自动评分器仅运行1个测试用例,核心问题在于自定义的AutoGraderTest类仅封装了单个测试方法,且通过exec执行代码的方式没有正确识别测试文件中的所有test_*方法。以下是具体的问题分析和修复方案:

问题分析

  1. 自定义测试类的局限性:你定义的AutoGraderTest只包含一个test_submission方法,unittest会将其视为单个测试用例,而非执行测试文件中所有的测试方法。
  2. exec执行方式的问题:直接用exec运行测试代码和提交代码,无法将测试文件中的UnitTest类下的所有测试方法注册到测试套件中,导致仅能统计到一个测试用例。

修复后的代码

import os
import unittest
import importlib.util
import sys

class gradeCode:
    
    def __init__(self, submissions_path, unit_test_path, constraints_path):
        self.submissions_path = submissions_path
        self.unit_test_path = unit_test_path
        self.constraints_path = constraints_path
        
    def print_report(self, report):
        for student_report in report:
            student_id = student_report['file']
            total_tests = student_report['total_tests']
            successful_tests = student_report['successful_tests']
            grade = student_report['grade']
            
            report_str = ''
            report_str += f'\n Student ID: {student_id}'
            report_str += f'\n {successful_tests} of {total_tests} tests passed.'
            report_str += f'\n Grade: {grade:.2f}%'
            report_str += f'\n---------------------------------------------------'
            
            print(report_str)
        
    def run_test(self):
        report = []
        
        # 动态加载测试模块
        test_spec = importlib.util.spec_from_file_location('unit_test_module', self.unit_test_path)
        test_module = importlib.util.module_from_spec(test_spec)
        test_spec.loader.exec_module(test_module)
        test_class = test_module.UnitTest
        
        for submission in os.listdir(self.submissions_path):
            if submission.endswith('.py'):
                submission_path = os.path.join(self.submissions_path, submission)
                submission_name = submission.strip('.py')
                
                # 动态加载学生提交的代码,替换测试依赖的calculator模块
                submission_spec = importlib.util.spec_from_file_location('calculator', submission_path)
                submission_module = importlib.util.module_from_spec(submission_spec)
                submission_spec.loader.exec_module(submission_module)
                sys.modules['calculator'] = submission_module
                
                # 收集测试类中所有test_*方法作为测试用例
                suite = unittest.TestLoader().loadTestsFromTestCase(test_class)
                
                # 执行测试并统计结果
                test_runner = unittest.TextTestRunner()
                test_results = test_runner.run(suite)
                
                total_tests = test_results.testsRun
                successful_tests = total_tests - len(test_results.failures) - len(test_results.errors)
                grade = (successful_tests / total_tests) * 100 if total_tests > 0 else 0
                
                submission_results = {
                    'file': submission_name,
                    'grade': grade,
                    'total_tests': total_tests,
                    'successful_tests': successful_tests
                }
                
                report.append(submission_results)
                # 清理模块缓存,避免影响下一个学生的测试
                del sys.modules['calculator']
                
        self.print_report(report)
        return report

关键改进点

  1. 动态模块加载:使用importlib.util替代exec,正确加载测试模块和学生提交的代码,解决测试文件中from calculator import Calculator的依赖问题。
  2. 自动收集测试用例:通过unittest.TestLoader().loadTestsFromTestCase(test_class)自动识别测试类中所有的test_*方法,确保所有测试用例被执行。
  3. 模块缓存清理:每次测试完成后删除sys.modules中的calculator模块,避免不同学生的代码相互干扰。

内容的提问来源于stack exchange,提问作者Sanjae Suresh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 01:45:32