Skip to content
Permalink
Browse files

Use parallel testing to greatly improve testing speeds

  • Loading branch information...
overshard committed Jul 3, 2018
1 parent efe92f5 commit 113c0e22bec235d975fd92c695927abf1fb24699
@@ -0,0 +1,23 @@
[run]
branch = True
parallel = true
concurrency = multiprocessing
source =
conf
core
api
sockets
registration
omit =
*/__init__.py
*/admin.py
*/apps.py
*/urls.py
*/tests*.py
*/migrations/*
*/management/*

[report]
precision = 1
show_missing = True
ignore_errors = True
@@ -30,4 +30,5 @@
/.vscode

# code coverage
/.coverage
/.coverage*
!/.coveragerc
@@ -37,14 +37,13 @@ def init_api_test_data():


class AppTestCase(TestCase):
def setUp(self):
pass

def test_api_config(self):
self.assertEqual(apps.get_app_config('api').name, 'api')


class ClientBrowseableApiTestCase(TestCase):

def setUp(self):
self.c, self.user = init_api_test_data()

@@ -83,6 +82,7 @@ def test_clients_post_unicode(self):


class ProjectBrowseableApiTestCase(TestCase):

def setUp(self):
self.c, self.user = init_api_test_data()

@@ -137,6 +137,7 @@ def test_projects_post_unicode(self):


class EntryBrowseableApiTestCase(TestCase):

def setUp(self):
self.c, self.user = init_api_test_data()

@@ -180,6 +181,7 @@ def test_entries_post(self):


class UserBrowseableApiTestCase(TestCase):

def setUp(self):
self.c, self.user = init_api_test_data()

@@ -189,6 +191,7 @@ def test_permission_get(self):


class PermissionBrowseableApiTestCase(TestCase):

def setUp(self):
self.c, self.user = init_api_test_data()

@@ -1,22 +1,18 @@
from django.contrib.auth.models import User
from django.test import TestCase, override_settings
from django.test import TestCase

from ..models import Conf, Site, SitePermission
from .models import Conf, Site, SitePermission


@override_settings(
STATICFILES_STORAGE='django.contrib.staticfiles.storage.StaticFilesStorage'
)
class ConfTestCase(TestCase):
def setUp(self):
pass

def test_conf_created(self):
site = Site.objects.create(domain='test.site', name='Test Site')
self.assertIsInstance(site.conf, Conf)


class SitePermissionTestCase(TestCase):

def setUp(self):
self.user = User.objects.create_user('Test User', 'test@user.com',
'test')
No changes.
@@ -16,8 +16,6 @@ class SeleniumTestCase(StaticLiveServerTestCase):
@classmethod
def setUpClass(cls):
options = FirefoxOptions()
# Delete MOZ_HEADLESS entirely if it's set to 0 to since Firefox will
# go into headless mode if the variable exists at all.
if environ.get('FIREFOX_HEADLESS') is not '0':
options.add_argument('-headless')
cls.driver = FirefoxDriver(firefox_options=options)
@@ -60,7 +58,7 @@ def logIn(self):
self.find('app')

def clear(self, element):
# Selenium's clear command doesn't always work
# Selenium's clear command doesn't work
value = element.get_attribute('value')
for character in value:
element.send_keys(Keys.BACK_SPACE)
@@ -1,68 +1,25 @@
from datetime import timedelta

from decimal import Decimal
from io import StringIO
from csv import DictReader

from django.test import TestCase, override_settings
from django.test import TestCase
from django.test import Client as HttpClient
from django.contrib.auth.models import User
from django.core.management import call_command

from faker import Factory

from conf.models import Site, SitePermission
from ..models import Client, Project, Entry, Task
from ..utils import parse_duration, duration_string, duration_decimal

from csv import DictReader

from io import StringIO

from faker import Factory


fake = Factory.create()


@override_settings(
STATICFILES_STORAGE='django.contrib.staticfiles.storage.StaticFilesStorage'
)
class ViewsTestCase(TestCase):
def setUp(self):
call_command('migrate', verbosity=0)
self.c = HttpClient()

fake_user = fake.simple_profile()
fake_password = fake.password()
user = User.objects.create_user(fake_user['username'],
fake_user['mail'], fake_password)
site_permission = SitePermission.objects.create(user=user)
site_permission.sites.set(Site.objects.filter(id=1))
site_permission.save()

self.c.login(username=fake_user['username'], password=fake_password)

def test_clients_view(self):
# Test with and without data in the database
page = self.c.get('/clients/')
self.assertEqual(page.status_code, 200)

call_command('fake', verbosity=0, iterations=1)
page = self.c.get('/clients/')
self.assertEqual(page.status_code, 200)

def test_timesheets_view(self):
# Test with and without data in the database
page = self.c.get('/timesheet/')
self.assertEqual(page.status_code, 200)

call_command('fake', verbosity=0, iterations=1)
page = self.c.get('/timesheet/')
self.assertEqual(page.status_code, 200)

def test_reports_export_view(self):
page = self.c.get('/reports/export/')
self.assertEqual(page.status_code, 403)


class ClientTestCase(TestCase):

def setUp(self):
call_command('migrate', verbosity=0)

@@ -87,10 +44,11 @@ def test_client_site_relationship(self):


class ProjectTestCase(TestCase):

def setUp(self):
call_command('migrate', verbosity=0)
self.user = User.objects.first()
self.client = Client.objects.create(name='Timestrap')
self.user = User.objects.create_user('testuser', 'test@example.com',
'testpassword')

def test_project_created(self):
Project.objects.create(client=self.client, name='Testing')
@@ -125,12 +83,12 @@ def test_project_estimate(self):


class EntryTestCase(TestCase):

def setUp(self):
call_command('migrate', verbosity=0)
self.user = User.objects.first()
client = Client.objects.create(name='Timestrap')
self.project = Project.objects.create(client=client, name='Testing')
self.user = User.objects.create_user('testuser', 'test@example.com',
'testpassword')

Entry.objects.create(
project=self.project,
@@ -191,6 +149,7 @@ def test_duration_decimal(self):


class ReportsTestCase(TestCase):

def setUp(self):
call_command('migrate', verbosity=0)
self.c = HttpClient()
@@ -266,11 +225,3 @@ def test_export_param_date_range(self):
'date__gte': str(dates[0]),
'date__lte': str(dates[1])
})


class CommandsTestCase(TestCase):
def setUp(self):
pass

def test_fake(self):
call_command('fake', verbosity=0)
@@ -6,18 +6,39 @@ const spawn = require('child_process').spawn;


gulp.task('coverage:test', gulp.series('build:webpack:production', () => {
let command = [
'run',
'coverage',
'run',
'--parallel-mode',
'--concurrency=multiprocessing',
'--rcfile=.coveragerc',
'manage.py',
'test',
'--parallel',
];

return spawn(
'pipenv',
['run', 'coverage', 'run', '--source=conf,core,api', 'manage.py', 'test'],
command,
{stdio: 'inherit'}
);
}));


gulp.task('coverage:combine', () => {
return spawn(
'pipenv',
['run', 'coverage', 'combine'],
{stdio: 'inherit'}
);
});


gulp.task('coverage:report', () => {
return spawn(
'pipenv',
['run', 'coverage', 'report', '-m'],
['run', 'coverage', 'report', '-m', '--rcfile=.coveragerc'],
{stdio: 'inherit'}
);
});
@@ -35,13 +56,26 @@ gulp.task('coverage:coveralls', () => {
gulp.task('coverage:clean', () => {
return del([
'client/static/**/*',
'.coverage',
'geckodriver.log',
'.coverage*',
'!.coveragerc',
]);
});


gulp.task('coverage:development', gulp.series('lint', 'coverage:test', 'coverage:report', 'coverage:clean'));
gulp.task('coverage:development', gulp.series(
'lint',
'coverage:test',
'coverage:combine',
'coverage:report',
'coverage:clean'
));


gulp.task('coverage:production', gulp.series('lint', 'coverage:test', 'coverage:report', 'coverage:coveralls'));
gulp.task('coverage:production', gulp.series(
'lint',
'coverage:test',
'coverage:combine',
'coverage:report',
'coverage:coveralls'
));
@@ -4,7 +4,10 @@ const spawn = require('child_process').spawn;


gulp.task('manage:test', gulp.series('build:webpack:production', () => {
const command = ['run', 'python', 'manage.py', 'test'];
let command = ['run', 'python', 'manage.py', 'test'];

const parallel = process.argv.indexOf('--parallel');
if (parallel !== -1) command.push(command.push('--parallel'));

const test = process.argv.indexOf('--test');
if (test !== -1) command.push(process.argv[test+1]);
@@ -15,7 +18,7 @@ gulp.task('manage:test', gulp.series('build:webpack:production', () => {
return spawn(
'pipenv',
command,
{stdio: 'inherit',env: process.env}
{stdio: 'inherit', env: process.env}
);
}));

0 comments on commit 113c0e2

Please sign in to comment.
You can’t perform that action at this time.