<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/write-end-to-end-tests-in-your-backend-s-language-nkjmo1egi" -->

---
title: Write End-to-End Tests in Your Backend’s Language
description: Test-data setup, not the browser interaction, is presented as the hardest part of end-to-end testing, so the choice of E2E tooling should follow the backend's...
canonical: https://daily.dev/posts/write-end-to-end-tests-in-your-backend-s-language-nkjmo1egi
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Write End-to-End Tests in Your Backend’s Language | daily.dev
og:description: Test-data setup, not the browser interaction, is presented as the hardest part of end-to-end testing, so the choice of E2E tooling should follow the backend's...
og:url: https://daily.dev/posts/write-end-to-end-tests-in-your-backend-s-language-nkjmo1egi
og:image: https://api.daily.dev/og/posts/nkjmO1egi.png
og:image:alt: Write End-to-End Tests in Your Backend’s Language
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Write End-to-End Tests in Your Backend’s Language

**[Atomic Spin](https://daily.dev/sources/atomicobject)** · 9 min read · 0 upvotes · 1 comments

## Summary

Test-data setup, not the browser interaction, is presented as the hardest part of end-to-end testing, so the choice of E2E tooling should follow the backend's language when it has capable browser tooling. Using a companion FastAPI, React, Playwright (Python bindings), SQLAlchemy, and PostgreSQL 17 example project run with pytest-xdist, the piece covers writing small creation helpers for persisted models, keeping meaningful scenario setup inline rather than hidden in shared scenario builders, structuring UI page objects around user intent, and designing test data (UUID-backed uniqueness, workspace/assignment scoping, per-worker session handling) so tests can run safely in parallel against one shared database. It closes with guidance on when to choose a different testing language instead of the backend's.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://spin.atomicobject.com/write-end-to-end-tests-in-your-backends-language>

## Questions this post answers

### How do you make Playwright end-to-end tests safe to run in parallel against a single shared PostgreSQL database?

Isolate tests by scenario ownership rather than by database instance: use UUID-backed values for fields with uniqueness constraints, keep references only to the exact records each test creates, sign in as a dedicated user per test, and query through workspace and assignment boundaries instead of relying on global counts or list positions. Each pytest-xdist worker gets its own process and database session, while PostgreSQL itself stays shared.

_Teams tuning parallel test suites can find more patterns like this on daily.dev._

### Should I write end-to-end test setup helpers that build a whole scenario or ones that build a single model?

Prefer small creation helpers centered on one persisted model, accepting relationships and overrides as parameters, over large shared scenario builders. Scenario-level helpers like create_task_scenario() accumulate boolean options over time and couple unrelated tests together, while helpers such as create_user() or create_task() keep only the relationships that explain a given test inline and visible in the test body itself.

_Developers refining test-data setup strategy can follow more testing design discussions on daily.dev._

## Community discussion

Top comments from developers on daily.dev.

**@nark3d** · 0 upvotes

> What happens to the setup helpers when a scenario needs two workspaces with different membership, since the inline approach reads well right up until the second dimension arrives and the helper signature grows an argument nobody understands.  Where does that land in practice, does the scenario just accept a longer body or does the helper take a shape you would not have chosen on day one?  I've ended up with one file too.  I have not missed the multi-file spec frameworks once.  How do you actually get one shared database and xdist to behave, because that is where I have lost the most time.

## Similar posts on daily.dev

- [My experience writing automated tests for a SPA](https://daily.dev/posts/my-experience-writing-automated-tests-for-a-spa-xevl2tw5c) · Lobsters · 0 upvotes · 0 comments
- [Software Testing with Playwright](https://daily.dev/posts/software-testing-with-playwright-lpwkoin9d) · freeCodeCamp · 6 upvotes · 0 comments
- [Getting started writing WordPress E2E Tests with Playwright](https://daily.dev/posts/getting-started-writing-wordpress-e2e-tests-with-playwright-5ztp5fdu2) · WordPress Developer · 13 upvotes · 0 comments
- [How to Run End-to-End Tests with Claude Code](https://daily.dev/posts/how-to-run-end-to-end-tests-with-claude-code-3dnmidy3n) · Towards Data Science · 1 upvotes · 0 comments

---

Tags: [#python](https://daily.dev/tags/python), [#testing](https://daily.dev/tags/testing), [#fastapi](https://daily.dev/tags/fastapi)

[View this post on daily.dev](https://daily.dev/posts/write-end-to-end-tests-in-your-backend-s-language-nkjmo1egi)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Write End-to-End Tests in Your Backend’s Language","url":"https://daily.dev/posts/write-end-to-end-tests-in-your-backend-s-language-nkjmo1egi","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/write-end-to-end-tests-in-your-backend-s-language-nkjmo1egi"},"datePublished":"2026-09-17T12:09:23.913Z","dateModified":"2026-09-17T12:09:49.320Z","description":"Test-data setup, not the browser interaction, is presented as the hardest part of end-to-end testing, so the choice of E2E tooling should follow the backend's...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/d1da9de362b9d81bc49288cba9c84f62?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/d1da9de362b9d81bc49288cba9c84f62?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Atomic Spin","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Atomic Spin","logo":"https://media.daily.dev/image/upload/t_logo,f_auto/v1/logos/e2af5ce3adaa403a8cf029268b62419f","url":"https://daily.dev/sources/atomicobject"},"commentCount":1,"discussionUrl":"https://daily.dev/posts/write-end-to-end-tests-in-your-backend-s-language-nkjmo1egi","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":1}],"keywords":"python,testing,fastapi","timeRequired":"PT9M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Atomic Spin","item":"https://daily.dev/sources/atomicobject"},{"@type":"ListItem","position":3,"name":"Write End-to-End Tests in Your Backend’s Language"}]}
{"@context":"https://schema.org","@type":"WebPage","@id":"https://daily.dev/posts/write-end-to-end-tests-in-your-backend-s-language-nkjmo1egi","comment":[{"@type":"Comment","text":"What happens to the setup helpers when a scenario needs two workspaces with different membership, since the inline approach reads well right up until the second dimension arrives and the helper signature grows an argument nobody understands.  Where does that land in practice, does the scenario just accept a longer body or does the helper take a shape you would not have chosen on day one?  I’ve ended up with one file too.  I have not missed the multi-file spec frameworks once.  How do you actually get one shared database and xdist to behave, because that is where I have lost the most time.","datePublished":"2026-09-20T10:28:39.334Z","url":"https://daily.dev/posts/nkjmO1egi#c-EqjU0NSS5","author":{"@type":"Person","name":"Adam","url":"https://daily.dev/nark3d","image":"https://avatars.githubusercontent.com/u/2162621?v=4"}}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/write-end-to-end-tests-in-your-backend-s-language-nkjmo1egi#faq","mainEntity":[{"@type":"Question","name":"How do you make Playwright end-to-end tests safe to run in parallel against a single shared PostgreSQL database?","acceptedAnswer":{"@type":"Answer","text":"Isolate tests by scenario ownership rather than by database instance: use UUID-backed values for fields with uniqueness constraints, keep references only to the exact records each test creates, sign in as a dedicated user per test, and query through workspace and assignment boundaries instead of relying on global counts or list positions. Each pytest-xdist worker gets its own process and database session, while PostgreSQL itself stays shared. Teams tuning parallel test suites can find more patterns like this on daily.dev."}},{"@type":"Question","name":"Should I write end-to-end test setup helpers that build a whole scenario or ones that build a single model?","acceptedAnswer":{"@type":"Answer","text":"Prefer small creation helpers centered on one persisted model, accepting relationships and overrides as parameters, over large shared scenario builders. Scenario-level helpers like create_task_scenario() accumulate boolean options over time and couple unrelated tests together, while helpers such as create_user() or create_task() keep only the relationships that explain a given test inline and visible in the test body itself. Developers refining test-data setup strategy can follow more testing design discussions on daily.dev."}}]}
```

