【问题标题】:I don't understand how this unit test is failing我不明白这个单元测试是如何失败的
【发布时间】:2011-08-01 20:41:29
【问题描述】:

这是单元测试的一部分:

from nose.tools import *
from testing import *


def test_directions():
        assert_equal(scan("north"), [('direction', 'north')])
        result = scan("north south east")
        assert_equal(result, [('direction', 'north'), ('direction', 'south'), ('direction', 'east')])

这是我的代码:

import string

def convert_number(s):
    try: 
        return int(s)
    except ValueError:
        return None

def scan(s):

    direction_words= ("north", "south", "east", "west", "down", "up", "left", "right", "back", "forwards", "backwards")
    verbs= ("go", "stop", "kill", "eat", "shoot", "run", "hide", "dodge")
    stop_words= ("the", "in", "of", "from", "at", "it")
    nouns= ("door", "bear", "princess", "cabinet", "gold", "money", "chest", "gun", "sword")        
    numbers= s.split()
    i=0
    j=0
    g=0
    m=0
    a=0
    b=0

    while a < len(numbers):
        if  type(convert_number(numbers[a])) == int:
            print [('number', int(numbers[a]) )]
            a += 1
        else:
            a += 1


    while i < len(direction_words):
        if direction_words[i] in s.split():
            s= string.lower(s)
            print [('direction', direction_words[i] ) ]
            i+=1 
        else:
            i+=1                

    while j < len(verbs):
        if verbs[j] in s.split():
            s= string.lower(s)
            print [('verb', verbs[j] )]
            j+=1
        else:
            j+=1    

    while g < len(stop_words):
        if stop_words[g] in s.split():
            s= string.lower(s)
            print [('stop', stop_words[g] )]
            g+=1
        else:
            g+=1

    while m < len(nouns):
        if nouns[m] in s.split():
            s= string.lower(s)
            print [('noun', nouns[m] )] 
            m+=1

        else:
            m+=1            

    while b< len(s.split()):      
        if numbers[b] not in nouns:
            if numbers[b] not in stop_words:
                if numbers[b] not in verbs:
                    if numbers[b] not in direction_words:
                        if  type(convert_number(numbers[b])) != int:   
                            print [('error', numbers[b] )]
                            b += 1

                        else:
                            b+=1    
                    else: b+=1
                else: b+=1
            else: b+=1
        else: b+=1


    else:
        return

当我在这里运行单元测试时,我得到了:

F
======================================================================
FAIL: tests.ex48_tests.test_directions
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
    self.test(*self.arg)
  File "/Users/Adam/Desktop/projects/ex48/tests/ex48_tests.py", line 6, in test_directions
    assert_equal(scan("north"), [('direction', 'north')])
AssertionError: None != [('direction', 'north')]
-------------------- >> begin captured stdout << ---------------------
[('direction', 'north')]

--------------------- >> end captured stdout << ----------------------

----------------------------------------------------------------------
Ran 1 test in 0.015s

FAILED (failures=1)

我不明白测试是如何失败的。当我在终端中运行程序时,它会产生与单元测试完全相同的结果。我不明白为什么它没有通过。

【问题讨论】:

    标签: python python-2.7


    【解决方案1】:

    因为你的函数是打印结果而不是返回它:

    while i < len(direction_words):
        if direction_words[i] in s.split():
            s= string.lower(s)
            print [('direction', direction_words[i] ) ] # <--- HERE
            i+=1 
    

    我还没有通读 LPTHW 的全部内容,所以我无法确切告诉你在本书的上下文中修复此代码的最佳方法是什么……但如果我正在编写它,我会返回一个列表,像这样:

    def scan(s):
        result = []
        ...
    
        while i < len(direction_words):
            if direction_words[i] in s.split():
                s= string.lower(s)
                # change the `print` statements to `result += …`
                result += [('direction', direction_words[i] ) ]
                i+=1 
    
        ...
        return result
    

    【讨论】:

    • 真棒非常有意义。不得不改变测试,因为现在扫描函数的结果是我创建的元组的顺序而不是句子的顺序。不要认为它会有所作为。
    • 酷。如果返回值的顺序不重要(例如,如果[('direction', 'north'), ('direction', 'south')][('direction', 'south'), ('direction', 'north')] 一样有效),那么您可以在比较列表时使用set built in (Wikipedia)。例如:assert_equal(set(result), set([('direction', 'north'), …])。这会起作用,因为集合是无序的,所以 set([1,2,3]) == set([3,2,1]).
    【解决方案2】:

    函数 scan() 返回无。所以断言:

    assert_equal(scan("north"), [('direction', 'north')])
    

    正确地失败了。

    【讨论】:

    • 啊,我明白了。非常感谢。
    【解决方案3】:

    您的 scan() 函数将文本打印到屏幕上并且不返回任何内容,但您的单元测试正在检查函数的返回值。

    您应该更改scan() 函数,以便它返回您感兴趣的输出,而不仅仅是打印它。

    【讨论】:

      【解决方案4】:

      您的代码有很多问题,但最明显的一个是scan 永远不会返回任何内容,因此result 始终是None

      【讨论】:

      • 我知道这是非常非常糟糕的代码。我对编程真的很陌生,现在已经解决这个问题大约 3 天了。它经历了很多变化和编辑,我确信可以以一种更优雅的方式完成。不过感谢您的帮助。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多