使用pyVows和Django进行单元测试
使用pyVows和Django进行单元测试,使用pyVows和Django进行异步测试
使用pyVows和Django进行单元测试(本文)
使用pyVows和Django进行综合测试
在上一篇文章中,我们讨论了使用神奇的pyVows和selenium来加速你的GUI测试。但GUI测试并不是全部。单元测试也是同样重要,甚至可以说更重要。我们可以继续使用pyVows进行单元测试。这不需要使用不同的工具。同样的工具。经过数以百计的测试后,与pyVows的异步特性相比。虽然你不会看到速度的提高,。特别是如果你的测试涉及大量的I/O。
所以我们看看使用pyVows进行单元测试。想象我们创建一些功能来管理用户的帐户,可能开始一个登录的表单。激活virtualenv之后,我们要做的第一件事是创建一个应用程序称为账户(这些天django的人认为一切都应该在应用程序和我是谁的讨论)。这是很容易用这个命令:
$pythonmanage.pystartappaccounts
这将创建一个名为账户的新目录包括:models.py,tests.py和views.py文件:
├──README.mdown
├──requirements.txt
└──tddapp
├──accounts
│├──__init__.py
│├──models.py
│├──tests.py
│└──views.py
├──manage.py
├──tddapp
│├──__init__.py
│├──settings.py
│├──urls.py
│└──wsgi.py
└──uitests.py
在我们的示例中我们首先要建立的是一个登录页面从/login访问。所以我们可以在url.py添加一个条目映射为/login到我们的函数:
urlpatterns=patterns('',
url(r'^login/$','accounts.views.login',name='login'),
一定要添加账户到INSTALLED_APPSsettings.py文件内。
此外,本文中使用的代码中可以到Github中找到相关的代码。
测试URL映射
上面的条目在urls.py很直接,它还是一个好方案来编写一个单元测试,以确保我们都连接正确。也在这种情况下一个测试是好的,必须确保有人并不意外改变这个url规则的某个时候。可能包括另一个url规则覆盖这一个。
所以我们可以改变accounts/tests.py文件像这样:
frompyvowsimportVows,expect
fromdjango_pyvows.contextimportDjangoHTTPContext
@Vows.batch
classLoginPageVows(DjangoHTTPContext):
defget_settings(self):
return"tddapp.settings"
deftopic(self):
self.start_server()
returnself.url("^login/$")
defurl_should_be_mapped_to_login_view(self,topic):
fromaccounts.viewsimportlogin
expect(topic).to_match_view(login)
这里我们正创建相同种类的测试例子,像我们在第一篇文章里做的。下面的事情需要记住:
@Vows.batch标记这个类作为测试配合pyVows运行。
从DjangoHTTPContext继承提供pyVows支持DjangoApp的测试。
重写了get_setting和返回设置文件的位置。您想要使用的文设置件是必要的,因为pyVows将自动启动Django服务器。注意:get_setting同样让测试不同产品使用不同的setting.py变得简单,比如你想使用更快的内存数据库。
测试的关键是url_should_be_mapped_to_login_view函数中使用内置django-pyvowstheto_match_view判断。使用to_match_view判断仅仅确保django将调用指定的函数。在这种情况下accounts.views.login用于指定的URL,这是我们作为我们的测试主题返回:
returnself.url("^login/$")
最初运行测试失败,直到我们将accounts.views.loginfunction函数添加到tests.py和然后添加login()函数到views.py:
fromdjango.httpimportHttpResponse
deflogin(request):
pass
为了正确地运行测试,我们可能需要提供一个到PYTHONPATH环境变量pyVows所以不会困惑在哪里找到我们的模块。为此我们应该从项目根目录运行pyVows命令行如下:
$envPYTHONPATH=$$PYTHONPATH:tddapp/pyvowstddapp/accounts/tests.py
这基本上是说tddapp/app目录添加到现有python测试的路径,然后运行pyvowstddapp/account/tests.py。这应该避免任何问题无法找到thesettings.py文件并确保所有导入工作。
测试view函数
现在我们知道我们urls.py映射到正确的视图下一个逻辑步骤是测试视图,以确保它期望是什么。所以用一个非常简单的登录视图更新views.py函数如下:
fromdjango.httpimportHttpResponse
deflogin(request):
returnHttpResponse("thisisalogin")
允许添加以下测试:
classLoginPageView(DjangoHTTPContext):
deftopic(self):
returnlogin(self.request())
defshould_return_valid_HTTP_Response(self,topic):
expect(topic).to_be_http_response()
defshould_return_login_page(self,topic):
expect(topic).to_have_contents_of("thisisalogin")
请注意,对于我们的话题我们是直接调用login视图函数和通过inself.request()。self.request是DjangoHTTPContext提供的一个helper函数,创建并返回一个新的HTTPRequest,从而使它简单测试Django的视图。
一旦我们从我们的loginview()函数返回值我们测试两种不同的特点:
它返回一个有效的HTTPResponse对象使用to_be_http_response()判断。
响应的内容是“thisisalogin”
进一步表明我们可以并行运行这些测试我们可以重构测试有点像这样:
fromaccounts.viewsimportlogin
frompyvowsimportVows,expect
fromdjango_pyvows.contextimportDjangoHTTPContext
@Vows.batch
classLoginPageVows(DjangoHTTPContext):
defget_settings(self):
return"tddapp.settings"
deftopic(self):
self.start_server()
classLoginPageURL(DjangoHTTPContext):
deftopic(self):
returnself.url("^login/$")
defurl_should_be_mapped_to_login_view(self,topic):
expect(topic).to_match_view(login)
classLoginPageView(DjangoHTTPContext):
deftopic(self):
returnlogin(self.request())
defshould_return_valid_HTTP_Response(self,topic):
expect(topic).to_be_http_response()
defshould_return_login_page(self,topic):
expect(topic).to_have_contents_of("thisisalogin")
请注意,我们在外面现在实例化Django服务器测试类LoginPageVows然后两个子类测试LoginPageURL的url好人LoginPageView的视图。如果你回想一下上一篇文章,兄弟类并行运行。所以URL测试和视图测试将同时运行上述class/test结构。
测试模版
可以说是上述视图功能太简单,在真实的应用程序中使用。往往在真实的应用程序中你会希望使用一些模板来显示您的动态视图。不要害怕,我们也可以用django-pyvows小于3版本测试。
说明,我们先为我们的登录视图创建一个模板。我们将创建的文件tddapp/accounts/templetes/login.html模板。代码的样子:
<html>
<head>
<title>Login</title>
</head>
<body>
<h1>PleaseLogin</h1>
<formmethod="POST"action="#"id="login-form">
<p>Username:<inputtype="text"id="username"/></p>
<p>Password:<inputtype="password"id="password"/></p>
<inputtype="submit"id="login"value="Login">
</form>
</body>
</html>
一旦创建了模板,我们只是改变login视图函数返回模板如下所示:
fromdjango.shortcutsimportrender
deflogin(request):
#returnHttpResponse("thisisalogin")
returnrender(request,'login.html')
渲染函数告诉登录函数返回login.html模板包在HTTPResponse对象。现在在测试方面,所有我们要做的就是改变ourshould_return_login_page检查是否登录。返回的html模板.这可以用以下更改:
defshould_return_login_page(self,topic):
fromdjango.template.loaderimportrender_to_string
loginTemplate=render_to_string("login.html")
expect(topic.content.decode()).to_equal(loginTemplate)
第一行should_return_login_page函数现在导入render_to_stringfunction以一个模板作为参数(和一个可选的上下文)并返回生成的html字符串。这将使超级容易确保我们正在返回login.html模板。我们通过生成模板使用render_to_string函数theshould_return_login_page函数(第二行)。然后我们比较HTTPResponse返回生成的loginTemplate(第三行)。
Python培训、Python培训班、Python培训机构,就选光环大数据!
还不够过瘾?想学习更多?点击 http://hadoop.aura.cn/python/ 进行Python学习!
大数据培训、人工智能培训、Python培训、大数据培训机构、大数据培训班、数据分析培训、大数据可视化培训,就选光环大数据!光环大数据,聘请专业的大数据领域知名讲师,确保教学的整体质量与教学水准。讲师团及时掌握时代潮流技术,将前沿技能融入教学中,确保学生所学知识顺应时代所需。通过深入浅出、通俗易懂的教学方式,指导学生更快的掌握技能知识,成就上万个高薪就业学子。 更多问题咨询,欢迎点击------>>>>在线客服!