【问题标题】:Python- Assertion error when performing nosetestsPython-执行鼻子测试时出现断言错误
【发布时间】:2016-09-09 00:28:04
【问题描述】:

我是 web.py 的新手。我正在关注 ex52 LPTHW ,我必须对测试文件夹中的所有测试进行鼻子测试。但是由于断言错误,我得到了 1 次失败的测试。我尝试阅读不同的断言错误以及它们发生的原因,但我无法弄清楚这一点。我尝试扩展服务器可能显示的错误,例如 500 Internal , 400 但它仍然未能通过测试。我已经创建了书中提到的其他代码:http://learnpythonthehardway.org/book/ex52.html

这是我的回溯:

C:\lpthw\gothonweb>cd tests

C:\lpthw\gothonweb\tests>nosetests
Traceback (most recent call last):
  File "C:\Python27\lib\site-packages\web\application.py", line 239, in process
    return self.handle()
  File "C:\Python27\lib\site-packages\web\application.py", line 230, in handle
    return self._delegate(fn, self.fvars, args)
  File "C:\Python27\lib\site-packages\web\application.py", line 420, in _delegate
    return handle_class(cls)
  File "C:\Python27\lib\site-packages\web\application.py", line 396, in handle_class
    return tocall(*args)
  File "C:\lpthw\gothonweb\bin\app.py", line 29, in GET
    return render.hello_form()
  File "C:\Python27\lib\site-packages\web\template.py", line 1017, in __getattr__
    t = self._template(name)
  File "C:\Python27\lib\site-packages\web\template.py", line 1014, in _template
    return self._load_template(name)
  File "C:\Python27\lib\site-packages\web\template.py", line 1001, in _load_template
    raise AttributeError, "No template named " + name
AttributeError: No template named hello_form

F...
======================================================================
FAIL: tests.app_tests.test_index
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\Python27\lib\site-packages\nose\case.py", line 197, in runTest
    self.test(*self.arg)
  File "C:\lpthw\gothonweb\tests\app_tests.py", line 12, in test_index
    assert_response(resp)
  File "C:\lpthw\gothonweb\tests\tools.py", line 5, in assert_response
    assert status in resp.status, "Expected response %r not in %r" % (status , resp.status)
AssertionError: Expected response '200' not in '500 Internal Server Error'

----------------------------------------------------------------------
Ran 4 tests in 0.562s

FAILED (failures=1) 

我的测试代码:app_tests.py

from nose.tools import *
from bin.app import app
from tests.tools import assert_response

def test_index():
    #check that we get a 404 on the / URL
    resp = app.request("/")
    assert_response(resp, status= "404")

    #test our first GET request to /hello
    resp = app.request("/hello")
    assert_response(resp)

    #make sure default values work for the form 
    resp = app.request("/hello" , method="POST")
    assert_response(resp , contains="Nobody")

    #test that we get expected values
    data = {'name':'Tejas','greet':'Ola!'}
    resp = app.request("/hello " , method= "POST", data=data)
    assert_response(resp , contains="Zed")

工具.py:

from nose.tools import *
import re

def assert_response(resp, contains=None, matches=None, headers=None, status= "200"):
    assert status in resp.status, "Expected response %r not in %r" % (status , resp.status)

    if status == "200":
        assert resp.data , "Response data is empty."

    if contains:
        assert contains in resp.data, "Response does not contain %r" % contains 

    if matches:
        reg = re.compile(matches)
        assert reg.matches(resp.data), "Response does not match %r" % matches 

    if headers:
        assert_equal(resp.headers , headers)

app.py 代码:

import web 
from gothonweb import map 

urls = (
       '/game' , 'GameEngine' ,
       '/' , 'Index',
        )

app = web.application(urls, globals())
#little hack so that debug mode works with sessions
if web.config.get('_session') is None:
    store= web.session.DiskStore('sessions')
    session= web.session.Session(app, store, initializer={'room':None})
    web.config._session = session 
else:
    session= web.config._session

render = web.template.render('templates/', base="layout")   

class Index(object):
    def GET(self):
        #this is used to "setup" the session with starting values
        session.room= map.START
        web.seeother("/game")

class GameEngine(object):
    def GET(self):
        if session.room:
            return render.show_room(room= session.room)
        else:
            #why is there here? do you need it?
             return render.you_died()

    def POST(self):
        form= web.input(action=None)

        if session.room and form.action:
            session.room= session.room.go(form.action)
        else:
            session.room= None        


if __name__ == "__main__" :
    app.run()

现在继续练习后,它给了我 2 个导入错误:

PS C:\lpthw\gothonweb\tests> nosetests
EE
======================================================================
ERROR: Failure: SyntaxError (invalid syntax (app.py, line 2))
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\Python27\lib\site-packages\nose\loader.py", line 418, in loadTestsFromName
    addr.filename, addr.module)
  File "C:\Python27\lib\site-packages\nose\importer.py", line 47, in importFromPath
    return self.importFromDir(dir_path, fqname)
  File "C:\Python27\lib\site-packages\nose\importer.py", line 94, in importFromDir
    mod = load_module(part_fqname, fh, filename, desc)
  File "C:\lpthw\gothonweb\tests\app_tests.py", line 2, in <module>
    from bin.app import app
  File "C:\lpthw\gothonweb\bin\app.py", line 2
    from gothonweb import map.py
                             ^
SyntaxError: invalid syntax

======================================================================
ERROR: Failure: ImportError (cannot import name map)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\Python27\lib\site-packages\nose\loader.py", line 418, in loadTestsFromName
    addr.filename, addr.module)
  File "C:\Python27\lib\site-packages\nose\importer.py", line 47, in importFromPath
    return self.importFromDir(dir_path, fqname)
  File "C:\Python27\lib\site-packages\nose\importer.py", line 94, in importFromDir
    mod = load_module(part_fqname, fh, filename, desc)
  File "C:\lpthw\gothonweb\tests\map_tests.py", line 2, in <module>
    from gothonweb import map
ImportError: cannot import name map

----------------------------------------------------------------------
Ran 2 tests in 0.002s

FAILED (errors=2)

目录结构:

C:/lpthw/
    gothonweb/
    bin build dist doc sessions Gothonweb templates tests map.py app.py 
tests/
map_tests.py
app_tests.py
__init__.py
tools.py

我应该怎么做才能修复错误?感谢您的建议。

【问题讨论】:

  • AssertionError 不是您的问题,而是您应该调查的 AttributeError。
  • 更具体地说,您的错误位于 app.py 中的第 29 行,您尚未提供代码。
  • 我已经用 app.py 代码更新了它,但我认为我们必须在练习中提前更改 app.py,所以它与之前的 app.py 不同,因为我们必须添加一些事情。
  • 你还在报错吗?
  • 现在当我运行鼻子测试时,我得到 2 个错误:都给出导入错误:无法从 gothonweb 导入地图。我不知道出了什么问题,因为结构对我来说是正确的,并且 import 语句就像书中给出的那样。

标签: python-2.7 web.py


【解决方案1】:

对于这个错误,

"AttributeError: 没有名为 hello_form 的模板"

使用绝对路径,看看是否可行,而不是

"render = web.template.render('templates/', base="layout")

试试:

"render = web.template.render('C:/lpthw/gothonweb/bin/templates', base="layout")

【讨论】:

    【解决方案2】:

    令人惊讶的是,您的测试与 app.py 无关。

    from nose.tools import *
    from bin.app import app
    from tests.tools import assert_response
    
    def test_index():
        #check that we get a 404 on the / URL
        resp = app.request("/")
        assert_response(resp, status= "404")
    
        #test our first GET request to /hello
        resp = app.request("/hello")
        assert_response(resp)
    
        #make sure default values work for the form 
        resp = app.request("/hello" , method="POST")
        assert_response(resp , contains="Nobody")
    
        #test that we get expected values
        data = {'name':'Tejas','greet':'Ola!'}
        resp = app.request("/hello " , method= "POST", data=data)
        assert_response(resp , contains="Zed")
    

    应用程序.py

    import web 
    from gothonweb import map 
    
    urls = (
           '/game' , 'GameEngine' ,
           '/' , 'Index',
            )
    
    app = web.application(urls, globals())
    #little hack so that debug mode works with sessions
    if web.config.get('_session') is None:
        store= web.session.DiskStore('sessions')
        session= web.session.Session(app, store, initializer={'room':None})
        web.config._session = session 
    else:
        session= web.config._session
    
    render = web.template.render('templates/', base="layout")   
    
    class Index(object):
        def GET(self):
            #this is used to "setup" the session with starting values
            session.room= map.START
            web.seeother("/game")
    
    class GameEngine(object):
        def GET(self):
            if session.room:
                return render.show_room(room= session.room)
            else:
                #why is there here? do you need it?
                 return render.you_died()
    
        def POST(self):
            form= web.input(action=None)
    
            if session.room and form.action:
                session.room= session.room.go(form.action)
            else:
                session.room= None        
    
    
    if __name__ == "__main__" :
        app.run()
    

    你能看出,它们是如何不相关的

    您的第一个测试表明您应该在“/”网址上获得 404,但只有在“/”不存在时才会发生这种情况。您的 app.py 代码清楚地显示了 Index 类中对 GET 的“/”调用。

    第二次测试,resp = app.request("/hello") 现在会给你一个 404 错误,因为 app.py 上不存在该 url

    第三个测试也是如此,因为 app.py 中的 url 元组中不存在“/hello”

    还有第五个测试

    虽然您的测试无效,但您遇到的主要问题是尝试从测试目录中执行自动化测试;这是错误的。

    C:\lpthw\gothonweb\tests> nosetests
    

    这不是正确的做法,您需要成为下面的目录才能使所有导入工作,例如在 app_tests 中,您尝试导入 bin/app.py 但它不在“测试”目录中

    改为这样做

    C:\lpthw\gothonweb> nosetests
    

    这样您需要的所有文件都将被导入
    回到 app_tests.py。我会写一个非常简单的测试,它实际上与 app.py 相关

     from bin.app import app
     from test.tools import assert_response
    
    def test_index():
        #check that we get a 303 on the / url
        #this is because web.seeother() will always send the browser this http code
        resp = app.request("/")
        assert_response(resp, status= "303")
    
    def test_game():
        #check that we get a 200 on /game
        resp = app.request("/game")
        assert_response(resp, status = '200')
    
        #check that we have response data on a form sumbit
        resp = app.request("/game", method = 'POST')
        aseert_response(resp.data)
    

    【讨论】:

      【解决方案3】:

      你得到的 assertion_error 因为你在这个目录中运行了nosetests

      /gothroweb/test

      你应该运行它 /gothroweb

      bin  docs  gothonweb  templates  tests
      
      ./bin:
      app.py  app.pyc  __init__.py  __init__.pyc
      
      ./docs:
      
      ./gothonweb:
      __init__.py  __init__.pyc
      
      ./templates:
      hello_form.html  index.html  layout.html
      
      ./tests:
      app_tests.py   __init__.py   test.html  tools.pyc
      app_tests.pyc  __init__.pyc  tools.py
      

      干杯

      【讨论】:

        猜你喜欢
        • 2011-07-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-25
        • 1970-01-01
        • 2020-07-07
        • 1970-01-01
        相关资源
        最近更新 更多