Testowanie aplikacji Django
14 July 2008
Comments
Testowanie kodu umożliwia szybkie wykrywanie błędów, a także kontrolę poprawnego funkcjonowania aplikacji. Przy wprowadzaniu zmian do kodu za pomocą testów sprawdzimy czy wprowadzone zmiany nie spowodowały błędów w innych częściach aplikacji. Django posiada zestaw narzędzi umożliwiających pisanie testów dla naszych aplikacji. Do dyspozycji mamy dwie metody pisania testów:
- Doctests - test zawarty do docstringu funkcji i emulujący "zachowanie" interaktywnego interpretera Pythona:
def my_func(a_list, idx): """ >>> a = ['larry', 'curly', 'moe'] >>> my_func(a, 0) 'larry' >>> my_func(a, 1) 'curly' """ return a_list[idx]
- Testy jednostkowe (Unit tests) - metody klasy dziedziczącej unittest.TestCase
import unittest class MyFuncTestCase(unittest.TestCase) def testBasic(self): a = ['larry', 'curly', 'moe'] self.assertEquals(my_func(a, 0), 'larry') self.assertEquals(my_func(a, 1), 'curly')
Docstringi
PEP 257 opisuje zasadę tworzenia doctestów. Django szuka takich testów w pliku models.py aplikacji, oraz pliku w tests.py jeżeli istnieje (w katalogu aplikacji):# models.py
from django.db import models
class Animal(models.Model):
"""
Zwierzęta wydające odgłosy
# Tworzymy zwierzęta
>>> lew = Animal.objects.create(name="lew", sound="ryk")
>>> kot = Animal.objects.create(name="kot", sound="mial")
# Niech powiedzą
>>> lew.speak()
'lew mówi "ryk"'
>>> kot.speak()
'kot mówi "mial"'
"""
name = models.CharField(max_length=20)
sound = models.CharField(max_length=20)
def speak(self):
return '%s mówi "%s"' % (self.name, self.sound)
Testy jednostkowe
Django szuka testów jednostkowy w pliku models.py szukając klas dziedziczących unittest.TestCase, a także w pliku tests.py także szukając klas dziedziczących unittest.TestCase. Przykład:import unittest
from myapp.models import Animal
class AnimalTestCase(unittest.TestCase):
def setUp(self):
self.lew = Animal.objects.create(name="lew", sound="ryk")
self.kot = Animal.objects.create(name="kot", sound="mial")
def testSpeaking(self):
self.assertEquals(self.lew.speak(), 'lew mówi "ryk"')
self.assertEquals(self.kot.speak(), 'kot mówi "mial"')
Wykonywanie testów
By wykonać wszystkie testy wystarczy polecenie:manage.py test
Można także wykonać testy dla danej aplikacji:
manage.py test NAZWA_APLIKACJI
Klient testów
test.client to klasa Pythona udająca prostą przeglądarkę. Umożliwia wykonywanie żądań GET i POST pobierając otrzymane dane. Umożliwia analizę jakie szablony i widoki zostały wykonane dla danego adresu URL, a także jakie dane zostały zwrócone. Przykład:>>> from django.test.client import Client
>>> c = Client()
>>> response = c.post('/login/', {'username': 'john', 'password': 'smith'})
>>> response.status_code
200
>>> response = c.get('/customer/details/')
>>> response.content
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 ...'
import unittest
from django.test.client import Client
class SimpleTest(unittest.TestCase):
def setUp(self):
# Every test needs a client.
self.client = Client()
def test_details(self):
# Issue a GET request.
response = self.client.get('/customer/details/')
# Check that the respose is 200 OK.
self.failUnlessEqual(response.status_code, 200)
# Check that the rendered context contains 5 customers.
self.failUnlessEqual(len(response.context['customers']), 5)
TestCase
Django posiada rozbudowaną wersję unittest.TestCase wzbogaconą o klienta testów i kilka innych funkcjonalności. Zamiast kodu:import unittest
from django.test.client import Client
class SimpleTest(unittest.TestCase):
def test_details(self):
client = Client()
response = client.get('/customer/details/')
self.failUnlessEqual(response.status_code, 200)
def test_index(self):
client = Client()
response = client.get('/customer/index/')
self.failUnlessEqual(response.status_code, 200)
from django.test import TestCase
class SimpleTest(TestCase):
def test_details(self):
response = self.client.get('/customer/details/')
self.failUnlessEqual(response.status_code, 200)
def test_index(self):
response = self.client.get('/customer/index/')
self.failUnlessEqual(response.status_code, 200)
RkBlog
Comment article