# How High Are Your Tests?

DevFeed: [How High Are Your Tests?](<https://devfeed.tech/articles/how-high-are-your-tests-22022.md>)

Original publisher: [Read original article](<http://www.wilfred.me.uk/blog/2019/03/04/how-high-are-your-tests/>)

Author: Wilfred Hughes

Published: 2019-03-04T00:00:00Z

Content type: article

Language: en

Sources: [Wilfred Hughes](<https://devfeed.tech/sources/wilfred-hughes.md>)

Topics: [Testing](<https://devfeed.tech/topics/testing.md>), [test](<https://devfeed.tech/topics/test.md>)

Tags: [database](<https://devfeed.tech/tags/database.md>), [http](<https://devfeed.tech/tags/http.md>), [testing](<https://devfeed.tech/tags/testing.md>), [unit-test](<https://devfeed.tech/tags/unit-test.md>), [unit-tests](<https://devfeed.tech/tags/unit-tests.md>), [web-browser](<https://devfeed.tech/tags/web-browser.md>)

## AI overview

The article proposes describing tests by a numerical "test height" from 0 to 100 instead of treating unit and integration tests as discrete categories. It contrasts isolated, fast, reliable unit tests with higher-level tests that use databases, full web stacks, HTTP, and browsers, which provide broader coverage but introduce slower execution, maintenance, variability, and less useful failures.

## Source excerpt

How big can a unit test be? How small can an integration test be? It's easy to argue about whether a test is a 'true' unit test or not. If we test several classes together, is it still a unit test? If we use a small external API, must we call it an integration test? The problem is that testing is a spectrum, but our terminology only allows discrete levels. Putting A Number On It I propose we treat testing as a numerical scale instead. Let's introduce a concept of test height, from 0 to 100. At 0, we have low-level, isolated unit tests. They run quickly, they run in process, and they're extremely reliable. No setup or teardown is required. At 100, we have high-level tests of full computer systems. We spin up an elaborate infrastructure of databases, external services, and exercise real protocols. Many processes run, runtime can be very variable, and flakiness is a continuing challenge. Let's look at some examples! We'll look at some code for a wiki website, and discuss different tests we could write. 20: An Isolated Test At the lowest level, we have code that only depends on its inputs. def slugify(value): if not value: return value # we don't want /, # or ? in our URL value = value.replace('/', '') .replace('#', '') .replace('?', '') # replace whitespace with underscores return re.sub('[-\\s]+', '_', value) We can easily write a small unit test for a function like this. There are no dependencies on external resources, or even external libraries. def test_slugify(): assert slugify('foo/bar baz?') == 'foobar_baz' This test only requires a single process, and our test assertion is simply looking at runtime values. 40: Running With A Scratch Database Our wiki stores its data in a database. Let's look at some view code that ultimately creates database rows. def create_user(request): if request.POST: form = UserForm(request.POST) if form.is_valid(): form.save() return HttpResponseRedirect(reverse('all_users')) else: form = UserForm() template_vars = {'form': form} return