Solution details

The first solution we will take a look at is what is given in the Django documentation itself, that is, test fixtures. Here, a test fixture is a file that contains a set of data that can be imported into your database to bring it to a known state. Typically, they are YAML or JSON files previously exported from the same database when it had some data.

For example, consider the following test case, which uses a test fixture:

from django.test import TestCase 
 
class PostTestCase(TestCase): 
    fixtures = ['posts'] 
 
    def setUp(self): 
        # Create additional common objects 
        pass 
 
    def test_some_post_functionality(self): 
        # By now fixtures and setUp() objects are loaded 
        pass 

Before setUp() gets called in each test case, the specified fixture, 'posts', gets loaded. Roughly speaking, the fixture will be searched for in the fixtures directory with certain known extensions, for example, app/fixtures/posts.json.

However, there are a number of problems with fixtures. Fixtures are static snapshots of the database. They are schema-dependent and have to be changed each time your models change. They also might need to be updated when your test-case assertions change. Updating a large fixture file manually, with multiple related objects, is no joke.

For all these reasons, many consider using fixtures as an anti-pattern. It is recommended that you use factories instead. A factory class creates objects of a particular class that can be used in tests. It is a DRY way of creating initial test objects.

Let's use a model's objects.create method to create a simple factory:

from django.test import TestCase 
from .models import Post 
 
class PostFactory: 
    def make_post(self): 
        return Post.objects.create(message="") 
 
class PostTestCase(TestCase): 
 
    def setUp(self): 
        self.blank_message = PostFactory().makePost() 
 
    def test_some_post_functionality(self): 
        pass 

Compared to using fixtures, the initial object creation and the test cases are all in one place. Fixtures load static data as is into the database without calling model-defined save() methods. Since factory objects are dynamically generated, they are more likely to run through your application's custom validations.

However, there is a lot of boilerplate in writing such factory classes yourself. The factory_boy package, based on thoughtbot's factory_girl, provides a declarative syntax for creating object factories.

When you rewrite the previous code to use factory_boy, we get the following result:

import factory 
from django.test import TestCase 
from .models import Post 
 
class PostFactory(factory.Factory): 
    class Meta: 
        model = Post 
    message = "" 
 
class PostTestCase(TestCase): 
 
    def setUp(self): 
        self.blank_message = PostFactory.create() 
        self.silly_message = PostFactory.create(message="silly") 
 
    def test_post_title_was_set(self): 
        self.assertEqual(self.blank_message.message, "") 
        self.assertEqual(self.silly_message.message, "silly") 

Note how clear the factory class becomes when written in a declarative fashion. The attribute's values do not have to be static. You can have sequential, random, or computed attribute values. If you prefer to have more realistic placeholder data such as US addresses, use the django-faker package.

In conclusion, I would recommend factories, especially factory_boy, for most projects that need initial test objects. You might still want to use fixtures for static data, such as lists of countries or t-shirt sizes, since they will rarely change.

Dire predictions

After the announcement of the impossible deadline, the entire team seemed to be suddenly out of time. They went from 4-week scrum sprints to 1-week sprints. Steve wiped every meeting off their calendars except "today's 30-minute catch-up with Steve." He preferred to have a one-on-one discussion if he needed to talk to someone at their desk.
At Madam O's insistence, the 30-minute meetings were held at a soundproof hall 20 levels below the SHIM headquarters. On Monday, the team stood around a large circular table with a gray metallic surface like the rest of the room. Steve stood awkwardly in front of it and made a stiff waving gesture with an open palm.

Even though everyone had seen the holographs come alive before, it never failed to amaze them each time. The disc almost segmented itself into hundreds of metallic squares and rose like miniature skyscrapers in a futuristic model city. It took them a second to realize that they were looking at a 3D bar chart.

"Our burn-down chart seems to be showing signs of slowing down. I am guessing it is the outcome of our recent user tests, which is a good thing. But..." Steve's face seemed to show the strain of trying to stifle a sneeze. He gingerly flicked his forefinger upward in the air, and the chart smoothly extended to the right.

"At this rate, projections indicate that we will miss the go-live by several days, at best. I did a bit of analysis and found several critical bugs late in our development. We can save a lot of time and effort if we can catch them early. I want to put your heads together and come up with some i..."

Steve clasped his mouth and let out a loud sneeze. The holograph interpreted this as a sign to zoom into a particularly uninteresting part of the graph. Steve cursed under his breath and turned it off. He borrowed a napkin and started noting down everyone's suggestions with an ordinary pen.

One of the suggestions that Steve liked most was a coding checklist listing the most common bugs, such as forgetting to apply migrations. He also liked the idea of involving users earlier in the development process for feedback. He also noted down some unusual ideas, such as a Twitter handle for tweeting the status of the continuous integration server.

At the close of the meeting, Steve noticed that Evan was missing. "Where is Evan?" he asked. "No idea," said Brad looking confused, "he was here a minute ago."
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.113.197