【问题标题】:Command-line invocation of unittests from __main__ failing从 __main__ 命令行调用单元测试失败
【发布时间】:2017-05-15 06:25:10
【问题描述】:

我正在用 Python 解决一些练习,并使用 unittest 来自动化我的代码的一些验证。一个程序可以很好地运行单个单元测试并且它通过了。第二个给出以下错误:

$ python s1c6.py
E
======================================================================
ERROR: s1c6 (unittest.loader._FailedTest)
----------------------------------------------------------------------
AttributeError: module '__main__' has no attribute 's1c6'

----------------------------------------------------------------------
Ran 1 test in 0.001s

FAILED (errors=1)

这是工作脚本的代码:

# s1c5.py
import unittest

import cryptopals


class TestRepeatingKeyXor(unittest.TestCase):
    def testCase(self):
        key = b"ICE"
        data = b"Burning 'em, if you ain't quick and nimble\nI go crazy when I hear a cymbal"
        expected = bytes.fromhex(
            "0b3637272a2b2e63622c2e69692a23693a2a3c6324202d623d63343c2a26226324272765272a282b2f20430a652e2c652a3124333a653e2b2027630c692b20283165286326302e27282f")
        self.assertEqual(expected, cryptopals.xorcrypt(key, data))


if __name__ == "__main__":
    unittest.main()

以及失败脚本的代码:

# s1c6.py
import unittest
import bitstring

import cryptopals


class TestHammingDistance(unittest.TestCase):
    def testCase(self):
        str1 = b'this is a test'
        str2 = b'wokka wokka!!!'
        expected = 37
        self.assertEqual(expected, hamming_distance(str1, str2))


def hamming_distance(str1, str2):
    temp = cryptopals.xor(str1, str2)
    return sum(bitstring.Bits(temp))


if __name__ == "__main__":
    unittest.main()

我看不出这两个程序之间的根本区别会导致一个错误而不是另一个错误。我错过了什么?

import itertools
import operator


def xor(a, b):
    return bytes(map(operator.xor, a, b))


def xorcrypt(key, cipher):
    return b''.join(xor(key, x) for x in grouper(cipher, len(key)))


def grouper(iterable, n):
    it = iter(iterable)
    group = tuple(itertools.islice(it, n))
    while group:
        yield group
        group = tuple(itertools.islice(it, n))

失败脚本的“原始”版本:

# s1c6_raw.py
import cryptopals

key = b"ICE"
data = b"Burning 'em, if you ain't quick and nimble\nI go crazy when I hear a cymbal"
expected = bytes.fromhex(
    "0b3637272a2b2e63622c2e69692a23693a2a3c6324202d623d63343c2a26226324272765272a282b2f20430a652e2c652a3124333a653e2b2027630c692b20283165286326302e27282f")
print(cryptopals.xorcrypt(key, data))

以上运行良好并打印出预期的输出。

【问题讨论】:

  • 如果您将代码放入失败的测试用例中,将其单独放入文件中(连同必要的导入)并运行它会发生什么?
  • @BrenBarn 如果我在 PyCharm 中将“失败”脚本作为“Python 测试”运行,它运行良好(目前通过,但这并不重要)。当我如图所示从命令行运行或使用 PyCharm 中的“Python”运行配置运行时,会发生“失败”。
  • @Code-Apprentice:好的。你能澄清一下你在 PyCharm 中做什么而不是在 PyCharm 中做什么?就像,有四种可能性:1)您从 PyCharm 运行单元测试代码; 2)您从命令行运行单元测试代码; 3) 你从 PyCharm 运行原始代码; 4)您从命令行运行原始代码。据我了解,您说#4 没有错误,但我不清楚其他的。
  • @BrenBarn 正如我所说,我不知道“Python 测试”在幕后所做的细节。我怀疑某些反射会以if 语句失败的方式导入我的脚本。
  • 显然我遗漏了一个重要细节:我正在运行带有命令行参数python s1c6.py s1c6.txt 的脚本,这似乎是导致错误的原因。

标签: python command-line runtime-error command-line-arguments python-unittest


【解决方案1】:

问题是我以不同的方式运行这两个脚本:

$ python s1c5.py

$ python s1c6.py s1c6.txt

由于unittest.main()解析命令行参数,第二种情况出现错误。如果我将命令行参数传递给第一个程序,我也会得到同样的错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-14
    • 2018-08-30
    • 1970-01-01
    • 2017-01-11
    • 2011-03-18
    • 1970-01-01
    相关资源
    最近更新 更多