test_example_validation.py 9.5 KB
# AIfeng/2025-01-27 14:30:00
"""
豆包ASR示例文件测试验证
验证example.py的可运行性和依赖完整性
"""

import unittest
import subprocess
import sys
import os
from pathlib import Path
import tempfile
import json


class TestExampleValidation(unittest.TestCase):
    """
    示例文件验证测试
    """
    
    def setUp(self):
        """测试初始化"""
        self.project_root = Path(__file__).parent.parent
        self.asr_path = self.project_root / 'asr' / 'doubao'
        self.example_path = self.asr_path / 'example.py'
        
    def test_example_file_exists(self):
        """测试示例文件是否存在"""
        self.assertTrue(self.example_path.exists(), f"示例文件不存在: {self.example_path}")
        
    def test_example_file_syntax(self):
        """测试示例文件语法是否正确"""
        try:
            # 使用python -m py_compile检查语法
            result = subprocess.run(
                [sys.executable, '-m', 'py_compile', str(self.example_path)],
                capture_output=True,
                text=True,
                cwd=str(self.asr_path)
            )
            self.assertEqual(result.returncode, 0, f"语法错误: {result.stderr}")
        except Exception as e:
            self.fail(f"语法检查失败: {e}")
            
    def test_required_dependencies(self):
        """测试必需的依赖是否存在"""
        required_files = [
            '__init__.py',
            'asr_client.py',
            'config_manager.py',
            'protocol.py',
            'service_factory.py',
            'audio_utils.py'
        ]
        
        for file_name in required_files:
            file_path = self.asr_path / file_name
            self.assertTrue(file_path.exists(), f"依赖文件不存在: {file_path}")
            
    def test_import_check(self):
         """测试导入检查"""
         # 创建临时测试脚本
         test_script = """# -*- coding: utf-8 -*-
import sys
from pathlib import Path

# 添加ASR路径
sys.path.insert(0, str(Path(__file__).parent))

try:
    # 测试example.py的导入是否成功
    import example
    print("SUCCESS: example.py imported successfully")
    
    # 检查关键函数是否存在
    required_attrs = ['ASRExamples', 'run_all_examples', 'create_sample_config']
    for attr in required_attrs:
        if hasattr(example, attr):
            print(f"SUCCESS: Found {attr}")
        else:
            print(f"WARNING: Missing {attr}")
            
except ImportError as e:
    print(f"IMPORT_ERROR: {e}")
    sys.exit(1)
except Exception as e:
    print(f"OTHER_ERROR: {e}")
    sys.exit(1)
"""
         
         with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f:
             f.write(test_script)
             temp_script = f.name
             
         try:
             result = subprocess.run(
                 [sys.executable, temp_script],
                 capture_output=True,
                 text=True,
                 cwd=str(self.asr_path)
             )
             
             self.assertEqual(result.returncode, 0, 
                            f"导入测试失败: {result.stdout} {result.stderr}")
             self.assertIn("SUCCESS", result.stdout, "导入测试未成功")
             
         finally:
             os.unlink(temp_script)
            
    def test_environment_variables_check(self):
         """测试环境变量检查"""
         # 创建环境变量检查脚本
         env_check_script = """# -*- coding: utf-8 -*-
import os

# 检查必需的环境变量
required_vars = ['DOUBAO_APP_KEY', 'DOUBAO_ACCESS_KEY']
missing_vars = []

for var in required_vars:
    if not os.getenv(var):
        missing_vars.append(var)

if missing_vars:
    print(f"MISSING_ENV_VARS: {','.join(missing_vars)}")
else:
    print("ENV_VARS_OK: All required environment variables are set")
"""
         
         with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f:
             f.write(env_check_script)
             temp_script = f.name
             
         try:
             result = subprocess.run(
                 [sys.executable, temp_script],
                 capture_output=True,
                 text=True
             )
             
             # 这个测试只是检查,不强制要求环境变量存在
             if "MISSING_ENV_VARS" in result.stdout:
                 print(f"警告: 缺少环境变量 - {result.stdout.strip()}")
             else:
                 print("环境变量检查通过")
                 
         finally:
             os.unlink(temp_script)
            
    def test_config_file_creation(self):
         """测试配置文件创建功能"""
         # 创建配置文件测试脚本
         config_test_script = """# -*- coding: utf-8 -*-
import sys
from pathlib import Path
import json
import tempfile

# 添加路径
sys.path.insert(0, str(Path(__file__).parent))

try:
    # 测试通过example.py访问ConfigManager
    import example
    
    # 检查是否能访问create_sample_config函数
    if hasattr(example, 'create_sample_config'):
        # 尝试创建示例配置
        config_path = example.create_sample_config()
        print(f"CONFIG_TEST_SUCCESS: Sample config created at {config_path}")
    else:
        print("CONFIG_TEST_SUCCESS: example.py imported without config creation")
    
except Exception as e:
    print(f"CONFIG_TEST_ERROR: {e}")
    sys.exit(1)
"""
         
         with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f:
             f.write(config_test_script)
             temp_script = f.name
             
         try:
             result = subprocess.run(
                 [sys.executable, temp_script],
                 capture_output=True,
                 text=True,
                 cwd=str(self.asr_path)
             )
             
             self.assertEqual(result.returncode, 0, 
                            f"配置测试失败: {result.stdout} {result.stderr}")
             self.assertIn("CONFIG_TEST_SUCCESS", result.stdout, "配置测试未成功")
             
         finally:
             os.unlink(temp_script)
            
    def test_audio_file_availability(self):
        """测试音频文件可用性"""
        # 检查项目中的音频文件
        audio_extensions = ['.wav', '.mp3', '.m4a', '.flac']
        audio_dirs = [
            self.project_root / 'audio',
            self.project_root / 'test' / 'audio',
            self.project_root / 'samples'
        ]
        
        found_audio_files = []
        for audio_dir in audio_dirs:
            if audio_dir.exists():
                for ext in audio_extensions:
                    found_audio_files.extend(list(audio_dir.glob(f'*{ext}')))
        
        # 检查根目录下的音频文件
        for ext in audio_extensions:
            found_audio_files.extend(list(self.project_root.glob(f'*{ext}')))
            
        if found_audio_files:
            print(f"找到音频文件: {[str(f) for f in found_audio_files[:3]]}")
        else:
            print("警告: 未找到测试音频文件")
            
    def test_example_help_output(self):
        """测试示例文件帮助输出"""
        try:
            # 尝试运行example.py --help或查看文档字符串
            result = subprocess.run(
                [sys.executable, str(self.example_path), '--help'],
                capture_output=True,
                text=True,
                cwd=str(self.asr_path),
                timeout=10
            )
            
            # 如果--help不支持,至少文件应该能被python解析
            if result.returncode != 0:
                # 尝试简单的语法检查
                result = subprocess.run(
                    [sys.executable, '-c', f'import ast; ast.parse(open("{self.example_path}").read())'],
                    capture_output=True,
                    text=True,
                    cwd=str(self.asr_path)
                )
                self.assertEqual(result.returncode, 0, f"文件解析失败: {result.stderr}")
                
        except subprocess.TimeoutExpired:
            print("示例文件运行超时(可能在等待输入)")
        except Exception as e:
            print(f"示例文件测试异常: {e}")


def run_validation_tests():
    """运行验证测试"""
    print("=== 豆包ASR示例文件验证测试 ===")
    
    # 创建测试套件
    suite = unittest.TestLoader().loadTestsFromTestCase(TestExampleValidation)
    
    # 运行测试
    runner = unittest.TextTestRunner(verbosity=2)
    result = runner.run(suite)
    
    # 输出总结
    print(f"\n=== 测试总结 ===")
    print(f"总测试数: {result.testsRun}")
    print(f"成功: {result.testsRun - len(result.failures) - len(result.errors)}")
    print(f"失败: {len(result.failures)}")
    print(f"错误: {len(result.errors)}")
    
    if result.failures:
        print("\n失败的测试:")
        for test, traceback in result.failures:
            error_msg = traceback.split('AssertionError: ')[-1].split('\n')[0]
            print(f"- {test}: {error_msg}")
    
    if result.errors:
        print("\n错误的测试:")
        for test, traceback in result.errors:
            error_msg = traceback.split('\n')[-2]
            print(f"- {test}: {error_msg}")
    
    return result.wasSuccessful()


if __name__ == '__main__':
    success = run_validation_tests()
    
    if success:
        print("\n✅ 示例文件验证通过,可以进行测试")
    else:
        print("\n❌ 示例文件验证失败,需要修复问题")
        
    sys.exit(0 if success else 1)