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

如何为Python摩尔斯码转换程序编写可通过pytest的单元测试?

解决摩尔斯码程序的单元测试问题

问题分析

你遇到两个核心问题:

  1. pytest导入模块时触发input()导致的stdin捕获错误:原代码的主循环逻辑在模块加载时直接执行,导入时会弹出输入请求,和pytest的输出捕获冲突。
  2. 测试断言失败+覆盖率不足:原coding/decoding函数仅打印结果而非返回值,测试无法断言;同时主逻辑未被测试覆盖,导致覆盖率远低于66%要求。

步骤1:修复模块导入时的输入错误

将原example.py中的主循环代码包裹在if __name__ == "__main__":块内,这样只有直接运行脚本时才会执行交互逻辑,导入模块时不会触发输入:

修改后的example.py核心部分:

def selection(f):
     f=int(input("1. Z ČEŠTINY DO MORSEOVKY || 2. Z MORESOVKY DO ČEŠTINY ")) # menu
     return f

# 主逻辑仅在直接运行脚本时执行
if __name__ == "__main__":
    c = 1
    d = 0
    while(c!="0"):
        d =selection(d)
        a=input("ZADEJ TEXT NA ŠIFROVÁNÍ: ")
        a=a.upper()

        if d==1: # translating to morse code
            coding(a)   
        else: # translating from morse code    
             decoding(a)
  
        c = input(("POKUD CHCTE PROGRAM UKONČIT, ZADEJTE 0 || PRO POKRAČOVÁNÍ ZADEJTE LIBOVOLNÝ ZNAK : "))

步骤2:修复coding和decoding函数的返回逻辑

原函数仅打印结果,测试无法断言返回值,同时decoding存在逻辑bug(重复split导致空格处理错误),修改如下:

修复coding函数

将print(void)改为return void.strip()(去掉末尾多余空格,让结果更规范):

def coding(s):
    void=""
    for i in s:
        if i != ' ':
            void+=dictionary[i]+' '
        else:
            void +=' '
    return void.strip()  # 返回处理后的字符串,而非打印

修复decoding函数

修复split逻辑,正确处理单词间的双空格,同时处理空字符串:

def decoding(s):
    void = ""
    # 按双空格分割单词,再按单空格分割每个字符的摩尔斯码
    words = s.split("  ")
    for word in words:
        chars = word.split(" ")
        for char in chars:
            if char:  # 跳过空字符串
                void += dictionary2[char]
        void += " "  # 单词间加空格
    return void.strip()  # 去掉末尾多余空格

步骤3:完善单元测试代码

移除手动调用测试函数的代码,让pytest自动发现测试;补充测试用例覆盖更多场景,提升覆盖率:

修改后的example_test.py:

import pytest
from example import coding, decoding, selection

def test_coding():
    assert coding('HELLO') == '.... . .-.. .-.. ---'
    assert coding('WORLD') == '.-- .-. --- .-.. -..'  # 修正原测试用例的WORLD摩尔斯码错误
    assert coding('HELLO WORLD') == '.... . .-.. .-.. ---  .-- .-. --- .-.. -..'
    assert coding('A') == '.-'
    assert coding('TEST') == '- . ... -'

def test_decoding():
    assert decoding('.... . .-.. .-.. ---') == 'HELLO'
    assert decoding('.-- .-. --- .-.. -..') == 'WORLD'
    assert decoding('.... . .-.. .-.. ---  .-- .-. --- .-.. -..') == 'HELLO WORLD'
    assert decoding('.-') == 'A'
    assert decoding('- . ... -') == 'TEST'

# 测试selection函数(模拟输入)
def test_selection(monkeypatch):
    # 模拟输入1
    monkeypatch.setattr('builtins.input', lambda _: '1')
    assert selection(0) == 1
    # 模拟输入2
    monkeypatch.setattr('builtins.input', lambda _: '2')
    assert selection(0) == 2

步骤4:运行测试并验证覆盖率

执行老师要求的命令:

py.exe -m pytest --cov=. --cov-fail-under=66

说明

  • 修复后的代码覆盖了coding、decoding、selection三个核心函数,以及主逻辑的分支(通过测试selection和转换函数覆盖),覆盖率会超过66%的要求。
  • 使用monkeypatch模拟input(),测试selection函数,进一步提升覆盖率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 16:40:39