From d48b964e7ab1f844ff2765c22affbe307b4d2884 Mon Sep 17 00:00:00 2001 From: Colin Goutte Date: Fri, 25 Aug 2023 09:59:34 +0200 Subject: [PATCH 1/7] Sphinx has an install issue to we skip it for now --- Pipfile | 2 -- 1 file changed, 2 deletions(-) diff --git a/Pipfile b/Pipfile index a58cd5b..d3a82e4 100644 --- a/Pipfile +++ b/Pipfile @@ -7,8 +7,6 @@ name = "pypi" [dev-packages] pytest = "*" -sphinx = "==7.1.2" -"sphinx.builders.linkcheck" = "*" [requires] python_version = "3.12" From fd3f14a7b8e6e1e9dfe0e1ae831ee2e449d9f36d Mon Sep 17 00:00:00 2001 From: Colin Goutte Date: Fri, 25 Aug 2023 10:15:00 +0200 Subject: [PATCH 2/7] First test for homepage --- Makefile | 7 ++++++- Pipfile | 1 + functionnal_test.py | 23 +++++++++++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 functionnal_test.py diff --git a/Makefile b/Makefile index 673af69..09bcf5a 100644 --- a/Makefile +++ b/Makefile @@ -12,11 +12,16 @@ run_dev: pipenv run python dev.py tdd: - git ls-files | entr pipenv run pytest --lf --nf + # nomerge git ls-files | entr pipenv run pytest --lf --nf + git ls-files | entr make functionnal_tests + test: pipenv run pytest $(opt) +functionnal_tests: + pipenv run python -m pytest functionnal_test.py + requirements: pipenv requirements > requirements.txt pipenv requirements --dev-only > requirements_dev.txt diff --git a/Pipfile b/Pipfile index d3a82e4..bbcf66c 100644 --- a/Pipfile +++ b/Pipfile @@ -7,6 +7,7 @@ name = "pypi" [dev-packages] pytest = "*" +selenium = "*" [requires] python_version = "3.12" diff --git a/functionnal_test.py b/functionnal_test.py new file mode 100644 index 0000000..508ba4e --- /dev/null +++ b/functionnal_test.py @@ -0,0 +1,23 @@ +import unittest + +from selenium import webdriver +from selenium.webdriver.common.by import By + + +server = "localhost" +port = 5000 + +base_url = f"http://{server}{':%d' % port if port else '' }" + + +class BaseFunctionnalTestCase(unittest.TestCase): + def setUp(self): + self.driver = webdriver.Firefox() + self.addCleanup(self._close) + + def test_homepage(self): + self.driver.get(base_url) + + def _close(self): + if self.driver: + self.driver.quit() From 4462b7c6fb395094135d90424c583425b1b79b42 Mon Sep 17 00:00:00 2001 From: Colin Goutte Date: Fri, 25 Aug 2023 10:34:36 +0200 Subject: [PATCH 3/7] Dev server automaticaly restarts and functional tests are green --- Makefile | 2 +- Pipfile | 2 ++ dev.py | 13 ++++++++++++- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 09bcf5a..669b781 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ install_dev: make requirements run_dev: - pipenv run python dev.py + git ls-files | entr -r pipenv run python dev.py tdd: # nomerge git ls-files | entr pipenv run pytest --lf --nf diff --git a/Pipfile b/Pipfile index bbcf66c..a630cd6 100644 --- a/Pipfile +++ b/Pipfile @@ -4,6 +4,8 @@ verify_ssl = true name = "pypi" [packages] +fastapi = "*" +uvicorn = "*" [dev-packages] pytest = "*" diff --git a/dev.py b/dev.py index 894eaff..0ce2447 100644 --- a/dev.py +++ b/dev.py @@ -1,2 +1,13 @@ +from fastapi import FastAPI +import uvicorn + +app = FastAPI() + + +@app.get("/") +async def root(): + return {"message": "Hello World"} + + if __name__ == "__main__": - print("dev.py file ok") + uvicorn.run(app, host="127.0.0.1", port=5000) From 89a6b4bead95616c48da84c3d6ae75974b18a4c5 Mon Sep 17 00:00:00 2001 From: Colin Goutte Date: Fri, 25 Aug 2023 10:36:37 +0200 Subject: [PATCH 4/7] Add doc on functional testing tools --- .gitignore | 2 ++ README.rst | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/.gitignore b/.gitignore index a5c14e5..54cd5e6 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ __pycache__/ .venv* *.py[o|c] **_build/ +geckodriver.log + diff --git a/README.rst b/README.rst index b18ac90..04893c8 100644 --- a/README.rst +++ b/README.rst @@ -39,3 +39,23 @@ if pipenv is *not* installed I suggest you have pipenv installed, this projet is writtent under python 3.12 and may work on other versiona We have a requirement of being virtualenv compatible while i will working with Pipenv. + + +Testing +------- + +Unitest should run flawlessly using make test, however functionnal testing may require some extra work. + +Functional testing requires *geckodriver* and *selenium* which is a driver to programatically control firefox (so one ca reproduce user behavior) + +.. code-block:: shell + + #debian + sudo apt-get install firefox-geckodriver + + # arch + sudo pacman -S geckodriver + + + + From 41bdbeebc607531add589a3eed8bf60c85130f1f Mon Sep 17 00:00:00 2001 From: Colin Goutte Date: Fri, 25 Aug 2023 10:47:46 +0200 Subject: [PATCH 5/7] test that API has a swagger UI --- functionnal_test.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/functionnal_test.py b/functionnal_test.py index 508ba4e..617677b 100644 --- a/functionnal_test.py +++ b/functionnal_test.py @@ -9,15 +9,25 @@ port = 5000 base_url = f"http://{server}{':%d' % port if port else '' }" +docs_url = f"{base_url}/docs" + class BaseFunctionnalTestCase(unittest.TestCase): def setUp(self): self.driver = webdriver.Firefox() self.addCleanup(self._close) - def test_homepage(self): + def test_app_homepage_is_reachale(self): self.driver.get(base_url) + def test_app_has_swagger_documentation(self): + swagger_header_content = "FastAPI 0.1.0 OAS 3.1" + + self.driver.get(docs_url) + + swagger = self.driver.find_elements(By.ID, "swagger-ui")[0] + assert swagger_header_content in swagger.text.replace("\n", "") + def _close(self): if self.driver: self.driver.quit() From 49b142e3060fdec32a29b750cfef1fa9daaffcb3 Mon Sep 17 00:00:00 2001 From: Colin Goutte Date: Fri, 25 Aug 2023 10:50:37 +0200 Subject: [PATCH 6/7] Refactor: only one instantiation of webdriver --- functionnal_test.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/functionnal_test.py b/functionnal_test.py index 617677b..0ae2cdf 100644 --- a/functionnal_test.py +++ b/functionnal_test.py @@ -13,9 +13,10 @@ docs_url = f"{base_url}/docs" class BaseFunctionnalTestCase(unittest.TestCase): - def setUp(self): - self.driver = webdriver.Firefox() - self.addCleanup(self._close) + @classmethod + def setUpClass(cls): + cls.driver = webdriver.Firefox() + cls.addClassCleanup(cls.driver.quit) def test_app_homepage_is_reachale(self): self.driver.get(base_url) @@ -27,7 +28,3 @@ class BaseFunctionnalTestCase(unittest.TestCase): swagger = self.driver.find_elements(By.ID, "swagger-ui")[0] assert swagger_header_content in swagger.text.replace("\n", "") - - def _close(self): - if self.driver: - self.driver.quit() From 641ded12adc1bae471b6d53797bdc0c79cebc2ff Mon Sep 17 00:00:00 2001 From: Colin Goutte Date: Fri, 25 Aug 2023 11:10:12 +0200 Subject: [PATCH 7/7] Add tooling and doc for our first usecase --- README.rst | 17 +++++++++++++++++ gitaliases.gitconfig | 12 ++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 gitaliases.gitconfig diff --git a/README.rst b/README.rst index 04893c8..f28350a 100644 --- a/README.rst +++ b/README.rst @@ -58,4 +58,21 @@ Functional testing requires *geckodriver* and *selenium* which is a driver to pr +Toolings +-------- + +Few useful git aliases may be found in `gitalias.gitconfig` to use them add the include directive to your .git/config file + +.. code-block:: + + [include] + path = ../gitaliases.gitconfig + + [core] + repositoryformatversion = 0 + filemode = true + bare = false + logallrefupdates = true + + diff --git a/gitaliases.gitconfig b/gitaliases.gitconfig new file mode 100644 index 0000000..8d62732 --- /dev/null +++ b/gitaliases.gitconfig @@ -0,0 +1,12 @@ +# Add this to your .git/config file +#[include] +# path = ../gitaliases.gitconfig + +[alias] + um = "!git checkout main && git pull && git checkout - " + resync = "! git um && git rebase -" + out-of-sync = branch --no-merged main --no-contains main # Thee branch derive from an old main + open = branch --no-merged main --contains main + integ = "! git resync && git checkout main && git merge --no-ff - " + icm = "! echo 'ok'" +