Showing posts with label testing. Show all posts
Showing posts with label testing. Show all posts
Jun 11, 2013
Oct 15, 2012
How to run Selenium in background in virtual display (Xvfb)
http://en.wikipedia.org/wiki/Xvfb
In the X Window System, Xvfb or X virtual framebuffer is an X11 server that performs all graphical operations in memory, not showing any screen output. From the point of view of the client, it acts exactly like any other server, serving requests and sending events and errors as appropriate. However, no output is shown. This virtual server does not require the computer it is running on to even have a screen or any input device. Only a network layer is necessary.
Xvfb is primarily used for testing
PyVirtualDisplay - a Python wrapper for Xvfb:
In the X Window System, Xvfb or X virtual framebuffer is an X11 server that performs all graphical operations in memory, not showing any screen output. From the point of view of the client, it acts exactly like any other server, serving requests and sending events and errors as appropriate. However, no output is shown. This virtual server does not require the computer it is running on to even have a screen or any input device. Only a network layer is necessary.
Xvfb is primarily used for testing
PyVirtualDisplay - a Python wrapper for Xvfb:
#!/usr/bin/env python
from pyvirtualdisplay import Display
from selenium import webdriver
display = Display(visible=0, size=(800, 600))
display.start()
# now Firefox will run in a virtual display.
# you will not see the browser.
browser = webdriver.Firefox()
browser.get('http://www.google.com')
print browser.title
browser.quit()
display.stop()
http://stackoverflow.com/questions/6183276/how-do-i-run-selenium-in-xvfb
Labels:
selenium,
testing,
virtual display,
xvfb
Aug 6, 2012
Tox to test across Python versions
Tox as is a generic virtualenv management and test command line tool you can use for:
- checking your package installs correctly with different Python versions and interpreters
- running your tests in each of the environments, configuring your test tool of choice
- acting as a frontend to Continuous Integration servers, greatly reducing boilerplate and merging CI and shell-based testing.
Labels:
python,
python versions,
testing,
version
Aug 1, 2012
Jul 30, 2012
Python 3.1 unittest2 framework new features
skip, skipIf and skipUnless decorators
class MyTestCase(unittest.TestCase):
@unittest.skip("demonstrating skipping")
def test_nothing(self):
self.fail("shouldn't happen")
@unittest.skipIf(mylib.__version__ < (1, 3),
"not supported in this library version")
def test_format(self):
# Tests that work for only a certain version of the library.
pass
@unittest.skipUnless(sys.platform.startswith("win"), "requires Windows")
def test_windows_support(self):
# windows specific testing code
pass
expectedFailure decoratorclass ExpectedFailureTestCase(unittest.TestCase):
@unittest.expectedFailure
def test_fail(self):
self.assertEqual(1, 0, "broken")
Jun 18, 2012
Jun 4, 2012
Apr 16, 2012
What type of test to write?
- Write system tests for your views.
- Write Selenium tests for Ajax, other JS/server interactions.
- Write unit tests for everything else (not strict).
- Test each case (code branch) where it occurs.
- One assert/action per test case method.
Change settings in tests
@override_settings(ALLOW_COMMENTS=True)
def test_comments_allowed(self):
# ...
https://github.com/carljm/django-testing-slides/blob/master/settings/30_good.md
Imposing no-DB discipline
from django.utils.unittest import TestCase
import mock
cursor_wrapper = mock.Mock()
cursor_wrapper.side_effect = RuntimeError("No touching the database!")
@mock.patch("django.db.backends.util.CursorWrapper", cursor_wrapper)
class NoDBTestCase(TestCase):
"""Will blow up if you database."""
https://github.com/carljm/django-testing-slides/blob/master/models/30_no_database.md
Apr 13, 2012
Testing models, forms
Form
Django Forms Deep Dive - Nathan R. Yergler
Fast test, slow test by Gary Bernhardt
Django Forms Deep Dive - Nathan R. Yergler
import unittest
class FormTests(unittest.TestCase):
def test_validation(self):
form_data = {
'name': 'X' * 300,
}
form = ContactForm(data=form_data)
self.assertFalse(form.is_valid())
Eventbrite just released a library on GitHub called rebar – https://github.com/eventbrite/rebarfrom rebar.testing import flatten_to_dict
form_data = flatten_to_dict(ContactForm())
form_data.update({
'name': 'X' * 300,
})
form = ContactForm(data=form_data)
assert(not form.is_valid())
ModelFormclass ModelFormTests(unittest.TestCase):
def test_validation(self):
form_data = {
'name': 'Test Name',
}
form = ContactForm(data=form_data)
self.assert_(form.is_valid())
self.assertEqual(form.instance.name, 'Test Name')
form.save()
self.assertEqual(
Contact.objects.get(id=form.instance.id).name,
'Test Name'
)
FormSetfrom rebar.testing import flatten_to_dict, empty_form_data
formset = ContactFormSet()
form_data = flatten_to_dict(formset)
form_data.update(
empty_form_data(formset, len(formset))
)
ModelFast test, slow test by Gary Bernhardt
def test_that_spam_posts_are_hidden(self):
post = Post(mark_post_as_spam=True)
discussion = Discussion(posts=[post])
assert discussion.visible_posts == []
Feb 17, 2012
Test Django transaction using mocking and TransactionTestCase
It's pretty simple using mock side_effect:
class MyTransactionTestCase(TransactionTestCase):
fixtures = ['some_fixture.json',]
@patch.object(SomeObjectInsideTransaction, 'some_method')
def test_disable_transaction(self, some_method):
some_method.side_effect = IOError("Unexpected exception")
try:
self.client.get('/your/view/url/')
except IOError:
pass
# assertions here
You have to use TransactionTestCase:
Django TestCase classes make use of database transaction facilities, if available, to speed up the process of resetting the database to a known state at the beginning of each test. A consequence of this, however, is that the effects of transaction commit and rollback cannot be tested by a Django TestCase class. If your test requires testing of such transactional behavior, you should use a Django TransactionTestCase.
Labels:
mocking,
testing,
transaction,
unittest
Feb 14, 2012
BDD (Lattuce и Splinter)
BDD (Behaviour Driven Development) - тесты пишутся на native english т.е. в итоге их смогут писать не программисты (тестировщики, кодеры или менеджеры)
Видео: http://python.mirocommunity.org/video/5169/djangocon-2011-testing-with-le
Используется Lattuce и надстройка над Selenium - Splinter
Видео: http://www.youtube.com/watch?v=OMLDHNaUMB8
+ Freshen + Behave
Видео: http://python.mirocommunity.org/video/5169/djangocon-2011-testing-with-le
Используется Lattuce и надстройка над Selenium - Splinter
Видео: http://www.youtube.com/watch?v=OMLDHNaUMB8
+ Freshen + Behave
Feb 2, 2012
Chaos Python
Add this into your functional tests and smoke it.
import sys, random
def chaos_trace(frame, event, arg):
if event == 'line' and random.random() < 0.000001:
raise MemoryError()
return chaos_trace
sys.settrace(chaos_trace)
You will get some lovely random failures injected into your code. A great way to find bugs, and make sure your reasoning is sound in the face of CHAOS!
Jan 20, 2012
Mocking
Mock basics
mock = Mock(name='bar', return_value='fish')
mock(1, 2, spam = 99)
# 'fish'
mock.assert_called_once_with(1, 2, spam = 99)
mock.called
# True
mock.call_count
# 1
mock.call_args
# ((1, 2), {'spam': 99})
From: http://blip.tv/pycon-us-videos-2009-2010-2011/pycon-2011-testing-with-mock-4899484Magic Mock basics
mock = MagicMock()
mock[5]
# <mock.Mock object at 0x2f90690>
mock.__str__.return_value = 'bzzzz'
str(mock)
# 'bzzzz'
Mock exceptions handling test
mock = Mock(side_effect=KeyError('boom'))
mock()
# Traceback (most recent call last)
# ....
# KeyError: 'boom'
Mock file write
>>> open_name = '%s.open' % __name__
>>> with patch(open_name, create=True) as mock_open:
... mock_open.return_value = MagicMock(spec=file)
...
... with open('/some/path', 'w') as f:
... f.write('something')
...
>>> file_handle = mock_open.return_value.__enter__.return_value
>>> file_handle.write.assert_called_with('something')
http://stackoverflow.com/questions/1289894/how-do-i-mock-an-open-used-in-a-with-statement-using-the-mock-framework-in-pyth
http://www.voidspace.org.uk/python/mock/magicmock.html
Mock file and raw_post_data
from mock import Mock, MagicMock
class SomeTestCase(TestCase):
def testRawPostData(self):
...
request = Mock(spec=request)
request.raw_post_data = 'myrawdata'
print request.raw_post_data # prints 'myrawdata'
file_mock = MagicMock(spec=file)
file_mock.read.return_value = 'myfiledata'
request.FILES = {'myfile': file_mock}
print request.FILES['myfile'].read() # prints 'myfiledata'
Mocking stdout
outstream = StringIO()
with patch('sys.stdout', new=outstream) as out:
...
actual_out = out.getvalue()
Video:
A Gentle Introduction to Mock for Python
Why Use Mock?
Mock and Django
Dec 9, 2011
Экстремальное программирование. Разработка через тестирование
Качество разработанных тестов оценивается методами:
- Покрытие операторов кода (statement coverage)
- Намеренное добавление дефекта (defect insertion)
Паттерны разработки основанной на тестах
- Тест. Отговорка что на тесты нет времени не совсем коректна, так как приложение все равно тестируется, но руками. Но автоматические тесты намного быстрее! Кроме того тесты снижают уровень стресса

- Изолированный тест (Isolated Test) - основная причина производительность
- Список тестов (Test List)
- Вначале тест (Test First)
- Вначале оператор assert (Assert First)
- Тестовые данные (Test Data)
- Понятные данные (Evident Data). Иногда, если данные используются только в одном методе, для лучшей читабельности можно использовать магические числа
Паттерны красной полосы
- One Test Step
- Starter Test (Начальный тест)
- Explanation Test (Объясняющий тест). Тесты могут служить для объяснения кода
- Learning Test (Тест для обучения)
- Another Test
- Regression Test
- Break

- Do Over (Начать сначала). Иногда лучше начать заново, чем пытаться довести до ума кривой код
- Cheap Desk, Nice Chear. Ну, в общем, хорошее кресло решает..
Паттерны тестирования
- Дочерний тест (Child Test)
- Mock Object
- Self Shunt (Самошунтирование). Как можно убедиться что один объект корректно взаимодействует с другим? Можно заставить тестируемый объект взаимодействовать не с целевым объектом, а с тестом.
def testNotification(self): self.count = 0 result = TestResult() result.addListener(self) WasRun('testMethod').run(result) self.assertEqual(1, self.count) def startTest(self): self.count = self.count + 1 - Log String (Строка журнал). Полезен когда важен порядок операций. Хорошо сочетается с Self Shunt. Объект-тест реализует методы шунтируемого интерфейса таким образом, что каждый из них добавляет строку в журнал, затем проверяется корректность этих записей.
- Crush Test Dummy (Тестирование обработки ошибок). Применяется когда надо протестировать как отрабатывает код по обработке ошибки, возникновение которой маловероятно. Для этого создается фэйковый объект который вместо реальной работы генерирует исключение.
- Broken Test
- Clean Check-In
Паттерны зеленой полосы
- Fake It (Подделка)
- Triangulate
- Obvious Implemetnation (Очевидная реализация)
- One To Many (От одного ко многим). Как реализовать работу с коллекцией объектов? Сначала реализуется для одного объекта, затем модернизируется для работы с коллекцией.
Паттерны xUnit
- Assertion
- Fixture
- External Fixture. Ресурсы освобождаются в tearDown()
- Test Method
- Exception Test
- All Tests
Nov 10, 2011
Setup module function (UnitTest)
The default ordering of tests created by the unittest test loaders is to group all tests from the same modules and classes together. This will lead to setUpClass / setUpModule (etc) being called exactly once per class and module. If you randomize the order, so that tests from different modules and classes are adjacent to each other, then these shared fixture functions may be called multiple times in a single test run.
import unittest
def setUpModule():
print 'Module setup...'
def tearDownModule():
print 'Module teardown...'
class Test(unittest.TestCase):
def setUp(self):
print 'Class setup...'
def tearDown(self):
print 'Class teardown...'
def test_one(self):
print 'One'
def test_two(self):
print 'Two'
Subscribe to:
Posts (Atom)