Skip to content

Instantly share code, notes, and snippets.

@aitoehigie
Created May 25, 2024 10:08
Show Gist options
  • Select an option

  • Save aitoehigie/5bff431082b67f52e993465334422e6d to your computer and use it in GitHub Desktop.

Select an option

Save aitoehigie/5bff431082b67f52e993465334422e6d to your computer and use it in GitHub Desktop.
# myapp/management/commands/make_smoke_tests.py
from django.core.management.base import BaseCommand
from django.urls import get_resolver, URLPattern, URLResolver
import re
import os
class Command(BaseCommand):
help = 'Generates smoke tests for projects.'
def add_arguments(self, parser):
parser.add_argument('output_file', nargs='?', default='smoke_tests.py', help='Path to the output file for the generated tests')
def handle(self, *args, **options):
urlconf = get_resolver(None)
output_file = options['output_file']
self.generate_smoke_tests(urlconf, output_file)
def generate_smoke_tests(self, urlconf, output_file, prefix=''):
with open(output_file, 'w') as f:
f.write("# Generated smoke tests\n")
f.write("from django.test import Client\n")
f.write("import pytest\n\n\n")
f.write("@pytest.mark.django_db\n")
f.write("class TestSmoke:\n")
f.write(" client = Client()\n\n")
self._write_smoke_tests(urlconf, f, prefix)
def _write_smoke_tests(self, urlconf, file, prefix):
for pattern in urlconf.url_patterns:
if isinstance(pattern, URLResolver):
self._write_smoke_tests(pattern, file, prefix + pattern.pattern.regex.pattern)
elif isinstance(pattern, URLPattern):
if pattern.name:
url = f"/{prefix}{pattern.pattern.regex.pattern}".replace('^', '').replace('$', '').rstrip('/')
params = self._extract_url_params(url)
url_with_params = self._build_url_with_params(url, params)
self._write_test(file, pattern.name, url_with_params, 'get')
self._write_test(file, pattern.name, url_with_params, 'post')
self._write_test(file, pattern.name, url_with_params, 'put')
self._write_test(file, pattern.name, url_with_params, 'delete')
def _extract_url_params(self, url):
return re.findall(r'<(\w+:\w+)>', url)
def _build_url_with_params(self, url, params):
for param in params:
param_type, param_name = param.split(':')
if param_type == 'int':
url = url.replace(f'<{param}>', '1')
elif param_type == 'slug':
url = url.replace(f'<{param}>', 'test-slug')
else:
url = url.replace(f'<{param}>', 'test')
return url
def _write_test(self, file, name, url, method):
test_name = f"test_{method}_{name}"
file.write(f" def {test_name}(self):\n")
file.write(f" response = self.client.{method}('{url}/')\n")
file.write(f" assert response.status_code == 200\n\n")
@abe-101

abe-101 commented May 28, 2024

Copy link
Copy Markdown

Thank for the improvements

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment