Skip to content

Instantly share code, notes, and snippets.

@soulshake
Forked from andresriancho/test_no_404.py
Last active April 23, 2019 09:41
Show Gist options
  • Save soulshake/67fb5f0a488cd4d18ea9568afb71b52a to your computer and use it in GitHub Desktop.
Save soulshake/67fb5f0a488cd4d18ea9568afb71b52a to your computer and use it in GitHub Desktop.
Check for broken links in your django site in a unittest!
import subprocess
import unittest
import re
import shlex
import os
import time
FNULL = open(os.devnull, 'w')
class TestNo404(unittest.TestCase):
SETUP = ['./manage.py migrate --run-syncdb --noinput']
# Ensure the address below is added to ALLOWED_HOSTS.
ADDRESS = '0.0.0.0:65123'
RUNSERVER = './manage.py runserver %s' % ADDRESS
# pip install LinkChecker==9.4.0
LINK_CHECKER = 'linkchecker http://%s --ignore-url=__debug__'
LINK_CHECKER_OUTPUT = "That's it. (.*?) links in (.*?) URLs checked. (.*?)"\
" warnings found. (.*?) errors? found."
def test_no_404(self):
self.setup_django_runserver()
runserver_proc = self.start_django_runserver()
try:
stdout, links, urls, warnings, errors = self.run_linkchecker(self.ADDRESS)
# Adjust your settings here
self.assertGreater(links, 100, stdout)
self.assertGreater(urls, 150, stdout)
self.assertEqual(warnings, 0, stdout)
self.assertEqual(errors, 0, stdout)
finally:
runserver_proc.terminate()
def setup_django_runserver(self):
for cmd in self.SETUP:
subprocess.check_call(shlex.split(cmd),
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
def start_django_runserver(self):
p = subprocess.Popen(shlex.split(self.RUNSERVER),
stdout=FNULL,
stderr=subprocess.STDOUT)
# Let the daemon start
time.sleep(2)
return p
def run_linkchecker(self, address):
p = subprocess.Popen(self.LINK_CHECKER % address, shell=True,
stdout=subprocess.PIPE,
stderr=FNULL)
stdoutdata, stderrdata = p.communicate()
if stdoutdata:
stdoutdata = stdoutdata.decode('utf-8')
if stderrdata:
stderrdata = stderrdata.decode('utf-8')
m = re.search(self.LINK_CHECKER_OUTPUT, stdoutdata)
if m is None:
self.assertTrue(False, stdoutdata)
links, urls, warnings, errors = (int(m.group(1)), int(m.group(2)),
int(m.group(3)), int(m.group(4)))
return stdoutdata, links, urls, warnings, errors
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment