{"id":20244594,"url":"https://github.com/billy0402/django-test-driven-development","last_synced_at":"2026-04-07T20:31:22.813Z","repository":{"id":165279268,"uuid":"221833358","full_name":"billy0402/django-test-driven-development","owner":"billy0402","description":"A learning project from the book 'Test-Driven Development with Python'.","archived":false,"fork":false,"pushed_at":"2024-05-03T14:44:32.000Z","size":511,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-03T15:28:50.212Z","etag":null,"topics":["course","django","python","selenium","sqlite","testing","web"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/billy0402.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-11-15T03:06:32.000Z","updated_at":"2024-05-03T14:44:35.000Z","dependencies_parsed_at":"2024-05-03T16:07:14.233Z","dependency_job_id":"0a18bfe1-5d42-466f-9488-f93d2490d789","html_url":"https://github.com/billy0402/django-test-driven-development","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/billy0402/django-test-driven-development","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/billy0402%2Fdjango-test-driven-development","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/billy0402%2Fdjango-test-driven-development/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/billy0402%2Fdjango-test-driven-development/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/billy0402%2Fdjango-test-driven-development/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/billy0402","download_url":"https://codeload.github.com/billy0402/django-test-driven-development/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/billy0402%2Fdjango-test-driven-development/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31528266,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-07T16:28:08.000Z","status":"ssl_error","status_checked_at":"2026-04-07T16:28:06.951Z","response_time":105,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["course","django","python","selenium","sqlite","testing","web"],"created_at":"2024-11-14T09:16:19.291Z","updated_at":"2026-04-07T20:31:22.680Z","avatar_url":"https://github.com/billy0402.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# django-test-driven-development\n\n## environment\n- [macOS 10.15.6](https://www.apple.com/tw/macos/catalina/)\n- [PyCharm 2020.2.1](https://www.jetbrains.com/pycharm/)\n- [Python 3.8.5](https://www.python.org/)\n- [Django 3.1.3](https://www.djangoproject.com/)\n- [Selenium 3.141.0](https://github.com/SeleniumHQ/selenium)\n\n## [Book](https://www.obeythetestinggoat.com/pages/book.html)\n![Test ALL the things](https://www.obeythetestinggoat.com/book/images/twp2_0401.png)\n\n## test command\n```shell script\n# 執行 Django 開發伺服器\n$ python manage.py runserver\n\n# 執行功能測試\n$ python manage.py test functional_tests\n\n# 執行單元測試\n$ python manage.py test app.todos\n```\n\n## TDD 流程\n- 功能測試 (使用者觀點)\n- 單元測試 (程式員觀點)\n- 單元測試/編程週期\n- 重構\n![The TDD process with functional and unit tests](https://www.obeythetestinggoat.com/book/images/twp2_0701.png)\n\n## 單元測試/編程週期\n1. (紅燈) 編寫失敗的單元測試\n2. (綠燈) 編寫最簡單的代碼使其通過 (作弊)\n3. (重構) 重構以獲取更有意義.更好的代碼\n    1. 消除重複\n    2. 三角關係 (編寫另一個測試)\n\n## 單元測試典型結構\n1. 設置 (Setup)\n2. 執行 (Exercise)\n3. 斷言 (Assert)\n    \n## Don’t Repeat Yourself (DRY)\n`不要寫出重複的程式`\n- 重複兩次 \u003e\u003e 可能重構，太早重構\n- 重複三次 \u003e\u003e 必須重構，立即重構\n\n## You ain’t gonna need it! (YAGNI)\n`你不會需要它！`\n```\n永遠在真正需要它們時，才實現它們，\n永遠不要在僅僅預想到需要它們時，就實現它們。\n```\n\n## 測試機部署\n\n### 安裝環境\n```shell\n$ sudo vim /etc/hosts\n127.0.0.1 localhost superlists-staging.edu.tw\n\n$ sudo pacman -S git python python-pipenv\n```\n\n### 安裝專案\n```shell\n$ export SITENAME=superlists-staging.edu.tw\n\n$ echo $SITENAME\n\n$ git clone https://github.com/billy0402/django-test-driven-development.git ~/sites/$SITENAME\n\n$ cd ~/sites/$SITENAME\n\n$ pipenv install \n\n$ pipenv shell\n\n$ python manage.py migrate --noinput\n\n$ python manage.py runserver\n\n$ STAGING_SERVER=$SITENAME python manage.py test functional_tests --failfast\n```\n\n### [安裝網頁伺服器](https://wiki.archlinux.org/index.php/Nginx)\n```shell\n$ sudo pacman -S nginx\n\n$ systemctl enable --now nginx\n\n$ su -\n\n$ mkdir -p /etc/nginx/sites-available/\n\n$ vim /etc/nginx/sites-available/$SITENAME.conf\n\n$ mkdir -p /etc/nginx/sites-enabled/\n\n$ ln -s /etc/nginx/sites-available/$SITENAME.conf /etc/nginx/sites-enabled/$SITENAME.conf\n\n$ readlink -f $SITENAME.conf\n\n$ vim /etc/nginx/nginx.conf\ninclude /etc/nginx/sites-enabled/*;\n\n$ systemctl reload nginx\n\n$ nginx -t\n```\n\n### 準生產部署\n```shell\n$ python manage.py collectstatic --noinput\n\n$ gunicorn core.wsgi:application\n\n$ set -a; source .env; set +a\n\n$ gunicorn core.wsgi:application --bind unix:/tmp/$SITENAME.socket\n```\n\n### 開機時啟動\n```shell\n$ sudo vim /etc/systemd/system/gunicorn-superlists-staging.edu.tw.service\n\n$ sudo systemctl daemon-reload\n\n$ sudo systemctl enable --now gunicorn-superlists-staging.edu.tw\n```\n\n## 自動化部署\n```shell\n$ pip install fabric3\n\n$ python -m fabric deploy:host=user@superlists.edu.tw\n\n$ cat ./deploy_tools/nginx.template.conf \\\n    | sed \"s/DOMAIN/superlists.edu.tw/g\" \\\n    | sudo tee /etc/nginx/sites-available/superlists.edu.tw\n\n$ sudo ln -s /etc/nginx/sites-available/superlists.edu.tw \\\n    /etc/nginx/sites-enabled/superlists.edu.tw\n\n$ sudo systemctl reload nginx\n\n$ cat ./deploy_tools/gunicorn-systemd.template.service \\\n    | sed \"s/DOMAIN/superlists.edu.tw/g\" \\\n    | sudo tee /etc/systemd/system/gunicorn-superlists.edu.tw.service\n\n$ sudo systemctl daemon-reload\n\n$ sudo systemctl enable --now gunicorn-superlists.edu.tw\n\n$ git tag LIVE\n$ export TAG=$(date +DEPLOYED-%F/%H%M)\n$ echo $TAG\n$ git tag $TAG\n$ git push origin LIVE $TAG\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbilly0402%2Fdjango-test-driven-development","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbilly0402%2Fdjango-test-driven-development","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbilly0402%2Fdjango-test-driven-development/lists"}