Skip to content

Commit a5f0da6

Browse files
committed
Add nose-json package
1 parent 0ba9879 commit a5f0da6

File tree

10 files changed

+84
-5
lines changed

10 files changed

+84
-5
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,7 @@ staticfiles/
3030
# npm
3131
npm-debug.log
3232

33+
# nose
34+
nosetests.json
35+
nosetests.xml
36+

Makefile

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.PHONY: test fasttest run lint pep8 eslint manage
1+
.PHONY: test fasttest run lint pep8 eslint manage report_failed_tests
22

33
# Project settings
44
LEVEL ?= development
@@ -33,6 +33,8 @@ SERVER_PORT ?= 8008
3333
# Other settings
3434
DJANGO_SERVER ?= runserver
3535
DJANGO_SHELL ?= shell_plus
36+
REPORT_FAILED_TEST ?= report_failed_tests
37+
REPORT_FAILED_TEST_BRANCHES ?= develop,master,test1
3638

3739
# Setup bootstrapper & Gunicorn args
3840
has_bootstrapper = $(shell python -m bootstrapper --version 2>&1 | grep -v "No module")
@@ -115,3 +117,7 @@ devserver: clean
115117
# Production Server
116118
server: clean pep8
117119
LEVEL=$(LEVEL) PYTHONPATH=$(PROJECT) $(GUNICORN) -b $(SERVER_HOST):$(SERVER_PORT) -w $(GUNICORN_WORKERS) -n $(GUNICORN_NAME) -t 60 --graceful-timeout 60 $(gunicorn_args) $(GUNICORN_ARGS) $(PROJECT).wsgi:application
120+
121+
# Reporting of failed cases:
122+
report_failed_tests:
123+
COMMAND="$(REPORT_FAILED_TEST) --branches $(REPORT_FAILED_TEST_BRANCHES) $(COMMAND_ARGS)" $(MAKE) manage

circle.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,14 @@ dependencies:
2525

2626
test:
2727
override:
28-
- TEST_ARGS='--with-xunit --with-json' make lint test
28+
- TEST_ARGS='--with-xunit --with-json --json-file="./nosetests.json"' make lint test
2929

3030
post:
3131
# - coveralls
3232
- mkdir -p $CIRCLE_TEST_REPORTS/junit/
3333
- "[ -r nosetests.xml ] && mv nosetests.xml $CIRCLE_TEST_REPORTS/junit/ || :"
3434
- "[ -r nosetests.json ] && mv nosetests.json $CIRCLE_TEST_REPORTS/junit/ || :"
35+
- COMMAND_ARGS='--target-branch develop' make report_failed_tests
3536

3637
# # Override /etc/hosts
3738
# hosts:

nosetests.xml

Lines changed: 0 additions & 1 deletion
This file was deleted.

requirements-dev.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ django-nose==1.4.2
44
flake8==2.3.0
55
flake8-import-order==0.5.3
66
flake8-pep257==1.0.3
7+
GitPython==1.0.2
78
https://github.com/zheller/flake8-quotes/tarball/aef86c4f8388e790332757e5921047ad53160a75#egg=flake8-quotes
89
nose==1.3.7
910
nose-json==0.2.4

src/authentication/tests.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,4 @@ def test_success(self):
77
pass
88

99
def test_failure(self):
10-
# self.fail('Failed test')
11-
pass
10+
self.fail('Failed test')

src/django_and_angular/management/__init__.py

Whitespace-only changes.

src/django_and_angular/management/commands/__init__.py

Whitespace-only changes.
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import re
2+
from git import Repo
3+
4+
from optparse import make_option
5+
6+
from xml.etree import cElementTree as ElementTree
7+
8+
from django.core.management.base import BaseCommand
9+
10+
11+
class Command(BaseCommand):
12+
13+
help = 'Creates JIRA issues for every failed case for specified branch'
14+
result_file = 'nosetests.xml'
15+
failure_row_re = re.compile(r'\s*File\s"(.*)",\sline\s(.*),.*')
16+
17+
option_list = BaseCommand.option_list + (
18+
make_option(
19+
'-b',
20+
'--branches',
21+
action='store',
22+
dest='branches',
23+
help='Affected branches',
24+
),
25+
make_option(
26+
'-t',
27+
'--target-branch',
28+
action='store',
29+
dest='target_branch',
30+
help='Target branch',
31+
)
32+
)
33+
34+
@staticmethod
35+
def parse_test_path(path):
36+
path, classname = path.rsplit('.', 1)
37+
path = path.replace('.', '/')
38+
return path, classname
39+
40+
def handle(self, *args, **options):
41+
repo = Repo()
42+
try:
43+
branches = [repo.heads[x] for x in options['branches'].split(',')]
44+
target = repo.heads[options['target_branch']]
45+
except IndexError as e:
46+
return 'Cannot find branch with error "{0}"'.format(e)
47+
if target != repo.head.ref:
48+
return 'Current branch "{0}" does not match provided CircleCI branch "{1}"'.format(
49+
repo.head.ref, target
50+
)
51+
elif target not in branches:
52+
return 'Skipping check for branch "{0}"'.format(repo.head.ref)
53+
54+
try:
55+
root = ElementTree.parse(self.result_file).getroot()
56+
if root.attrib['errors']:
57+
for testcase in root:
58+
for failure in testcase:
59+
print('Failure for {}'. format(testcase.attrib['name']))
60+
path, classname = self.parse_test_path(testcase.attrib['classname'])
61+
print path, classname
62+
for (file_path, line_number) in re.findall(self.failure_row_re, failure.text):
63+
if path in file_path:
64+
print repo.git.blame('HEAD', file_path)
65+
else:
66+
return 'No errors'
67+
except IOError:
68+
return 'File "{0}" does not exist'.format(self.result_file)

src/django_and_angular/settings/defaults.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
'compressor',
4242
'authentication',
4343
'posts',
44+
'django_and_angular',
4445
)
4546

4647
MIDDLEWARE_CLASSES = (

0 commit comments

Comments
 (0)