什么是测试和QUOT的最佳做法;不同层"在Django? [英] What are the best practices for testing "different layers" in Django?

查看:115
本文介绍了什么是测试和QUOT的最佳做法;不同层"在Django?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的不可以新来测试,但得到了与建议的烂摊子真的很困惑的在Django测试不同的层次。

I'm NOT new to testing, but got really confused with the mess of recommendations for testing different layers in Django.

一些建议(他们是正确的),以避免文档测试在模型中,因为它们不维护...

Some recommend (and they are right) to avoid Doctests in the model as they are not maintainable...

还有人说,不使用灯具,因为它们比的辅助功能,例如..

Others say don't use fixtures, as they are less flexible than helper functions, for instance..

还有的人谁使用的模拟的对象打两组。第一组认为,使用模拟和隔离系统的其余部分,而另一组preFER为停止嘲讽和开始测试 ..

There are also two groups of people who fight for using Mock objects. The first group believe in using Mock and isolating the rest of the system, while another group prefer to Stop Mocking and start testing..

所有我所提到的,大多是在问候的测试模型。 功能测试是另一个故事(使用test.Client()VS WebTest的VS等)

All I have mentioned above, were mostly in regards to testing models. Functional testing is an another story (using test.Client() VS webTest VS etc. )

用于测试不同的层ANY 维护,extandible和有道?

Is there ANY maintainable, extandible and proper way for testing different layers??

更新

我知道在2012 PYCON 卡尔迈耶的谈话的..

I am aware of Carl Meyer's talk at PyCon 2012..

推荐答案

更新2012年8月7日

我可以告诉你我的单元测试的做法正在pretty也为我自己的目的,我会给你我的理由:

I can tell you my practices for unit testing that are working pretty well for my own ends and I'll give you my reasons:

1.-使用赛程的只为是必要的测试,但没有信息打算改变,例如,你需要为每一个测试用户,你这样做使用基础夹具创建用户。

1.- Use Fixtures only for information that is necessary for testing but is not going to change, for example, you need a user for every test you do so use a base fixture to create users.

2:使用一个工厂来创建你的对象,我个人喜欢 FactoryBoy (这是来自FactoryGirl这是一个Ruby库)。我创建了一个名为factories.py为每一个应用程序在哪里保存所有这些对象单独的文件。这样,我让开了测试文件,我需要这使得很多更易读,易维护的所有对象。这个方法的很酷的事情是,你创建一个可如果你想测试基于从工厂的一些物体上别的修改的基础对象。此外,它不依赖于Django的,所以当我迁移这些对象,当我开始使用MongoDB的,需要对其进行测试,一切顺利。现在阅读的工厂后,这是常见的说:我为什么要使用固定装置,然后。由于这些装置应该不会改变从工厂所有额外的好东西是那种无用的,Django支持夹具很好的开箱。

2.- Use a factory to create your objects, I personally love FactoryBoy (this comes from FactoryGirl which is a ruby library). I create a separate file called factories.py for every app where I save all these objects. This way I keep off the test files all the objects I need which makes it a lot more readable and easy to maintain. The cool thing about this approach is that you create a base object that can be modified if you want to test something else based on some object from the factory. Also it doesn't depend on django so when I migrated these objects when I started using mongodb and needed to test them, everything was smooth. Now after reading about factories it's common to say "Why would I want to use fixtures then". Since these fixtures should never change all the extra goodies from factories are sort of useless and django supports fixtures very well out of the box.

3 .-我模拟,因为这些电话让我的测试非常缓慢,他们依靠的东西,没有什么调用外部服务,与我的code是对还是错。例如,如果我的鸣叫我的测试中,我测试它正确地鸣叫,复制响应,并模拟了对象,因此它的每一次返回确切的答复没有做实际调用。有时也还是不错的,测试出问题时,并嘲讽为是巨大的。

3.- I Mock calls to external services, because these calls make my tests very slow and they depend on things that have nothing to do with my code being right or wrong. for example, if I tweet within my test, I do test it to tweet rightly, copy the response and mock that object so it returns that exact response every time without doing the actual call. Also sometimes is good to test when things go wrong and mocking is great for that.

4.-我使用一个集成服务器(詹金斯是这里我的建议),它运行测试每次我推到我的临时服务器,如果他们失败,它给我发电子邮件。这下好了,因为它发生在我身上了很多,我打破别的东西在我的最后一个变化,我忘了运行测试。它也给你其他东西像一个覆盖报告, pylint的 /的 JSLint的 / PEP8 验证和存在大量的插件,您可以在设置不同的统计数据。

4.- I use an integration server (jenkins is my recommendation here) which runs the tests every time I push to my staging server and if they fail it sends me an email. This is just great since it happens to me a lot that I break something else in my last change and I forgot to run the tests. It also gives you other goodies like a coverage report, pylint/jslint/pep8 verifications and there exists a lot of plugins where you can set different statistics.

关于您的测试前端问题,Django带有一些<一个href=\"https://docs.djangoproject.com/en/dev/topics/testing/?from=olddocs#module-django.test.client\">helper功能的一个基本方式来处理这个问题。

About your question for testing front end, django comes with some helper functions to handle this in a basic way.

这是我个人使用,就可以得到火,职位,登录用户,等等。这是对我来说足够。我不倾向于使用完整的前端测试引擎像硒,因为我觉得这是矫枉过正,以测试任何东西,除了业务层。我相信有些人会有所不同,它总是取决于你正在努力。

This is what I personally use, you can fire gets, posts, login the user, etc. that's enough for me. I don't tend to use a complete front end testing engine like selenium since I feel it's an overkill to test anything else besides the business layer. I am sure some will differ and it always depends on what you are working on.

另外我看来,Django的1.4配备了一个非常方便的<一个href=\"https://docs.djangoproject.com/en/dev/topics/testing/?from=olddocs#django.test.LiveServerTestCase\">integration在浏览器框架。

Besides my opinion, django 1.4 comes with a very handy integration for in-browser frameworks.

我会以身作则应用,在那里所以它更容易理解,我可以将此做法。让我们创建一个非常基本的博客的应用程序:

I'll set an example app where I can apply this practices so it is more understandable. Let's create a very basic blog app:

结构

blogger/
    __init__.py
    models.py
    fixtures/base.json
    factories.py
    tests.py

models.py

 from django.db import models

 class Blog(models.Model):
     user = models.ForeignKey(User)
     text = models.TextField()
     created_on = models.DateTimeField(default=datetime.now())

灯具/ base.json

[
{
    "pk": 1,
    "model": "auth.user",
    "fields": {
        "username": "fragilistic_test",
        "first_name": "demo",
        "last_name": "user",
        "is_active": true,
        "is_superuser": true,
        "is_staff": true,
        "last_login": "2011-08-16 15:59:56",
        "groups": [],
        "user_permissions": [],
        "password": "IAmCrypted!",
        "email": "test@email.com",
        "date_joined": "1923-08-16 13:26:03"
    }
}
]

factories.py

import factory
from blog.models import User, Blog

class BlogFactory(factory.Factory):
    FACTORY_FOR = Blog

    user__id = 1
    text = "My test text blog of fun"

tests.py

class BlogTest(TestCase):
    fixtures = ['base']  # loads fixture

    def setUp(self):
        self.blog = BlogFactory()
        self.blog2 = BlogFactory(text="Another test based on the last one")

    def test_blog_text(self):
        self.assertEqual(Blog.objects.filter(user__id=1).count(), 2)

    def test_post_blog(self):
        # Lets suppose we did some views
        self.client.login(username='user', password='IAmCrypted!')
        response = self.client.post('/blogs', {'text': "test text", user='1'})

        self.assertEqual(response.status, 200)
        self.assertEqual(Blog.objects.filter(text='test text').count(), 1)

    def test_mocker(self):
        # We will mock the datetime so the blog post was created on the date
        # we want it to
        mocker = Mock()
        co = mocker.replace('datetime.datetime')
        co.now()
        mocker.result(datetime.datetime(2012, 6, 12))

        with mocker:
            res = Blog.objects.create(user__id=1, text='test')

        self.assertEqual(res.created_on, datetime.datetime(2012, 6, 12))

    def tearDown(self):
        # Django takes care of this but to be strict I'll add it
        Blog.objects.all().delete()

注意我用的一些具体技术的例子的缘故(其中尚未BTW测试)。

Notice I am using some specific technology for the sake of the example (which haven't been tested btw).

我要坚持,这可能不是标准的最佳实践(我怀疑它的存在),但它正在pretty很适合我。

I have to insist, this may not be the standard best practice (which I doubt it exists) but it is working pretty well for me.

这篇关于什么是测试和QUOT的最佳做法;不同层&QUOT;在Django?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆