Hey Our CircleCI takes a bit too long for our taste and makes iterating very difficult.
I am trying to set up code splititng our in our config but it seems like the command circleci tests glob "/**/tests.py"
takes like forever to run… We have around 1086 tests. This number comes from Djangos test runner.
The point of the splitting is of course to make it faster on CI, but the provided command hangs for 10m and then exits… not sure what i do wrong?
Our monorepo consits of a lot of small tests.py
files, but also nested folder structure: such as tests
folders with integration
and unit
test folders, in which test_
files sit.
Please take a look at the config and suggest big mistakes we might make.
version: 2.1
orbs:
node: circleci/node@5.0.0
python: circleci/python@2.0.1
browser-tools: circleci/browser-tools@1.2.4
workflows:
version: 2
build:
jobs:
- build_frontend:
filters:
branches:
ignore: /^master$/
- build_backend:
filters:
branches:
ignore: /^master$/
- run_tests:
filters:
branches:
ignore: /^master$/
requires:
- build_backend
- build_frontend
executors:
backend:
docker:
- image: cimg/python:3.9.9-browsers
environment:
DATABASE_URL: postgres://postgres:postgres@localhost/postgres?sslmode=disable
PARALLEL_BUILD_FRONTEND: 1
- image: postgres:latest
environment:
POSTGRES_HOST_AUTH_METHOD: trust
jobs:
build_frontend:
executor: node/default
resource_class: large
steps:
- checkout
- run: git log --format="%H" -n1 web_ui/frontend > frontend-git-revision.txt && cat frontend-git-revision.txt
- restore_cache:
key: frontendbuild-{{ checksum "frontend-git-revision.txt" }}
- restore_cache:
key: v1-npm-deps-{{ checksum "web_ui/frontend/package-lock.json" }}
- run:
name: "Build frontend"
command: |
./scripts/build_frontend.sh
- run:
name: "Extract frontend translations"
command: |
npm run --prefix web_ui/frontend extract-translations > /dev/null
- save_cache:
key: frontendbuild-{{ checksum "frontend-git-revision.txt" }}
paths:
- "web_ui/frontend"
- "web_ui/static/dist"
- "web_ui/frontend/locale/messages.pot"
- save_cache:
key: v1-npm-deps-{{ checksum "web_ui/frontend/package-lock.json" }}
paths:
- "web_ui/frontend/node_modules"
- persist_to_workspace:
root: .
paths:
- locale
- web_ui/frontend
- web_ui/static/dist
- web_ui/frontend/node_modules
build_backend:
executor: backend
resource_class: xlarge
steps:
- checkout
- run:
name: "Install system dependencies"
command: |
sudo apt-get update && sudo apt-get install -y gettext
- python/install-packages:
pkg-manager: pip
pip-dependency-file: requirements-dev.txt
pypi-cache: true
cache-version: venv-v1.0-{{ checksum "requirements-dev.txt" }}
- run:
name: "Check that no model changes are missing migrations"
command: |
./manage.py makemigrations --check
make_test_files:
executor: backend
resource_class: xlarge
steps:
- checkout
- python/install-packages:
pkg-manager: pip
pip-dependency-file: requirements-dev.txt
pypi-cache: true
cache-version: venv-v1.0-{{ checksum "requirements-dev.txt" }}'
- run:
command: |
set -e
# get all test files
TESTFILES=$(circleci tests glob "/**/tests.py")
echo $TESTFILES | tr ' ' '\n' | sort | uniq > circleci_test_files.txt
cat circleci_test_files.txt
TESTFILES=$(circleci tests split --split-by=timings circleci_test_files.txt)
# massage filepaths into format manage.py test accepts
TESTFILES=$(echo $TESTFILES | tr "/" "." | sed 's/.py//g')
echo $TESTFILES
./manage.py test --keepdb --parallel 8 --exclude-tag=functional --timing
run_tests:
executor: backend
parallelism: 5
resource_class: xlarge
steps:
- checkout
- attach_workspace:
at: .
- browser-tools/install-chrome
- browser-tools/install-chromedriver
- python/install-packages:
pkg-manager: pip
pip-dependency-file: requirements-dev.txt
pypi-cache: true
cache-version: venv-v1.0-{{ checksum "requirements-dev.txt" }}
- run:
name: "Backend tests"
command: |
./manage.py test --keepdb --parallel 10 --exclude-tag=functional --timing
- run: git log --format="%H" -n1 web_ui/frontend > frontend-git-revision.txt && cat frontend-git-revision.txt
- restore_cache:
key: frontendbuild-{{ checksum "frontend-git-revision.txt" }}
- run:
name: "Functional tests"
command: |
./manage.py test --tag functional
- store_artifacts:
path: /tmp/artifacts
- store_artifacts:
path: test-results
- store_test_results:
path: test-results
The way our setup works is:
- build frontend first
- build backend
- attach both to a workspace where we run functional and unit tests
As mentioned, we would like to split up our unit tests, but the provided config in the docs does not work, as the glob never finishes, even if we narrow down the pattern.
Many thanks .)