
johnp
Python Testing with pytest - Chapter 5 example c AttributeError: 'module' object has no attribute 'config'
Running the examples in chapter 5 c under pytest 5.4.1 causes an AttributeError: ‘module’ object has no attribute ‘config’.
In particular the code:
$ cd /path/to/code/ch5/c/tasks_proj/tests/func
$ pytest --tb=no test_api_exceptions.py -k TestAdd
causes:
(bopytest) [user@computer func]$ pytest -v test_api_exceptions.py -k TestAdd
==================================================== test session starts =====================================================
platform linux -- Python 3.8.3, pytest-5.4.1, py-1.8.1, pluggy-0.13.1 -- /home/user/.local/share/virtualenvs/bopytest/bin/python
cachedir: .pytest_cache
rootdir: /home/user/Projects/bopytest/ch5/c/tasks_proj/tests, inifile: pytest.ini
collected 9 items / 7 deselected / 2 selected
test_api_exceptions.py::TestAdd::test_missing_summary PASSED [ 50%]
test_api_exceptions.py::TestAdd::test_done_not_bool
INTERNALERROR> Traceback (most recent call last):
INTERNALERROR> File "/home/user/.local/share/virtualenvs/bopytest/lib/python3.8/site-packages/_pytest/main.py", line 191, in wrap_session
INTERNALERROR> session.exitstatus = doit(config, session) or 0
INTERNALERROR> File "/home/user/.local/share/virtualenvs/bopytest/lib/python3.8/site-packages/_pytest/main.py", line 247, in _main
INTERNALERROR> config.hook.pytest_runtestloop(session=session)
INTERNALERROR> File "/home/user/.local/share/virtualenvs/bopytest/lib/python3.8/site-packages/pluggy/hooks.py", line 286, in __call__
INTERNALERROR> return self._hookexec(self, self.get_hookimpls(), kwargs)
INTERNALERROR> File "/home/user/.local/share/virtualenvs/bopytest/lib/python3.8/site-packages/pluggy/manager.py", line 93, in _hookexec
INTERNALERROR> return self._inner_hookexec(hook, methods, kwargs)
INTERNALERROR> File "/home/user/.local/share/virtualenvs/bopytest/lib/python3.8/site-packages/pluggy/manager.py", line 84, in <lambda>
INTERNALERROR> self._inner_hookexec = lambda hook, methods, kwargs: hook.multicall(
INTERNALERROR> File "/home/user/.local/share/virtualenvs/bopytest/lib/python3.8/site-packages/pluggy/callers.py", line 208, in _multicall
INTERNALERROR> return outcome.get_result()
INTERNALERROR> File "/home/user/.local/share/virtualenvs/bopytest/lib/python3.8/site-packages/pluggy/callers.py", line 80, in get_result
INTERNALERROR> raise ex[1].with_traceback(ex[2])
INTERNALERROR> File "/home/user/.local/share/virtualenvs/bopytest/lib/python3.8/site-packages/pluggy/callers.py", line 187, in _multicall
INTERNALERROR> res = hook_impl.function(*args)
INTERNALERROR> File "/home/user/.local/share/virtualenvs/bopytest/lib/python3.8/site-packages/_pytest/main.py", line 272, in pytest_runtestloop
INTERNALERROR> item.config.hook.pytest_runtest_protocol(item=item, nextitem=nextitem)
INTERNALERROR> File "/home/user/.local/share/virtualenvs/bopytest/lib/python3.8/site-packages/pluggy/hooks.py", line 286, in __call__
INTERNALERROR> return self._hookexec(self, self.get_hookimpls(), kwargs)
INTERNALERROR> File "/home/user/.local/share/virtualenvs/bopytest/lib/python3.8/site-packages/pluggy/manager.py", line 93, in _hookexec
INTERNALERROR> return self._inner_hookexec(hook, methods, kwargs)
INTERNALERROR> File "/home/user/.local/share/virtualenvs/bopytest/lib/python3.8/site-packages/pluggy/manager.py", line 84, in <lambda>
INTERNALERROR> self._inner_hookexec = lambda hook, methods, kwargs: hook.multicall(
INTERNALERROR> File "/home/user/.local/share/virtualenvs/bopytest/lib/python3.8/site-packages/pluggy/callers.py", line 208, in _multicall
INTERNALERROR> return outcome.get_result()
INTERNALERROR> File "/home/user/.local/share/virtualenvs/bopytest/lib/python3.8/site-packages/pluggy/callers.py", line 80, in get_result
INTERNALERROR> raise ex[1].with_traceback(ex[2])
INTERNALERROR> File "/home/user/.local/share/virtualenvs/bopytest/lib/python3.8/site-packages/pluggy/callers.py", line 187, in _multicall
INTERNALERROR> res = hook_impl.function(*args)
INTERNALERROR> File "/home/user/.local/share/virtualenvs/bopytest/lib/python3.8/site-packages/_pytest/runner.py", line 85, in pytest_runtest_protocol
INTERNALERROR> runtestprotocol(item, nextitem=nextitem)
INTERNALERROR> File "/home/user/.local/share/virtualenvs/bopytest/lib/python3.8/site-packages/_pytest/runner.py", line 100, in runtestprotocol
INTERNALERROR> reports.append(call_and_report(item, "call", log))
INTERNALERROR> File "/home/user/.local/share/virtualenvs/bopytest/lib/python3.8/site-packages/_pytest/runner.py", line 190, in call_and_report
INTERNALERROR> hook.pytest_runtest_logreport(report=report)
INTERNALERROR> File "/home/user/.local/share/virtualenvs/bopytest/lib/python3.8/site-packages/pluggy/hooks.py", line 286, in __call__
INTERNALERROR> return self._hookexec(self, self.get_hookimpls(), kwargs)
INTERNALERROR> File "/home/user/.local/share/virtualenvs/bopytest/lib/python3.8/site-packages/pluggy/manager.py", line 93, in _hookexec
INTERNALERROR> return self._inner_hookexec(hook, methods, kwargs)
INTERNALERROR> File "/home/user/.local/share/virtualenvs/bopytest/lib/python3.8/site-packages/pluggy/manager.py", line 84, in <lambda>
INTERNALERROR> self._inner_hookexec = lambda hook, methods, kwargs: hook.multicall(
INTERNALERROR> File "/home/user/.local/share/virtualenvs/bopytest/lib/python3.8/site-packages/pluggy/callers.py", line 208, in _multicall
INTERNALERROR> return outcome.get_result()
INTERNALERROR> File "/home/user/.local/share/virtualenvs/bopytest/lib/python3.8/site-packages/pluggy/callers.py", line 80, in get_result
INTERNALERROR> raise ex[1].with_traceback(ex[2])
INTERNALERROR> File "/home/user/.local/share/virtualenvs/bopytest/lib/python3.8/site-packages/pluggy/callers.py", line 187, in _multicall
INTERNALERROR> res = hook_impl.function(*args)
INTERNALERROR> File "/home/user/.local/share/virtualenvs/bopytest/lib/python3.8/site-packages/_pytest/terminal.py", line 446, in pytest_runtest_logreport
INTERNALERROR> res = self.config.hook.pytest_report_teststatus(report=rep, config=self.config)
INTERNALERROR> File "/home/user/.local/share/virtualenvs/bopytest/lib/python3.8/site-packages/pluggy/hooks.py", line 286, in __call__
INTERNALERROR> return self._hookexec(self, self.get_hookimpls(), kwargs)
INTERNALERROR> File "/home/user/.local/share/virtualenvs/bopytest/lib/python3.8/site-packages/pluggy/manager.py", line 93, in _hookexec
INTERNALERROR> return self._inner_hookexec(hook, methods, kwargs)
INTERNALERROR> File "/home/user/.local/share/virtualenvs/bopytest/lib/python3.8/site-packages/pluggy/manager.py", line 84, in <lambda>
INTERNALERROR> self._inner_hookexec = lambda hook, methods, kwargs: hook.multicall(
INTERNALERROR> File "/home/user/.local/share/virtualenvs/bopytest/lib/python3.8/site-packages/pluggy/callers.py", line 208, in _multicall
INTERNALERROR> return outcome.get_result()
INTERNALERROR> File "/home/user/.local/share/virtualenvs/bopytest/lib/python3.8/site-packages/pluggy/callers.py", line 80, in get_result
INTERNALERROR> raise ex[1].with_traceback(ex[2])
INTERNALERROR> File "/home/user/.local/share/virtualenvs/bopytest/lib/python3.8/site-packages/pluggy/callers.py", line 187, in _multicall
INTERNALERROR> res = hook_impl.function(*args)
INTERNALERROR> File "/home/user/Projects/bopytest/ch5/c/tasks_proj/tests/conftest.py", line 88, in pytest_report_teststatus
INTERNALERROR> if report.failed and pytest.config.getoption("nice"):
INTERNALERROR> AttributeError: module 'pytest' has no attribute 'config'
From the digging I have done it seems that the capability to do
pytest.config
from
pytest.config.getoption('nice'):
was deprecated in pytest 4.0 and removed from pytest 5.0.
What did work for me was:
def pytest_report_header(config):
"""Thank tester for running tests."""
if config.getoption("nice"):
return "Thanks for running the tests."
def pytest_report_teststatus(config, report):
"""Turn failures into opportunities."""
if report.when == "call":
if report.failed and config.getoption("nice"):
return (report.outcome, "O", "OPPORTUNITY for improvement")
Cheers
John
Most Liked

brianokken
Author of Python Testing with pytest
“nice” workaround, John.
2
Popular Pragmatic Bookshelf topics

Some minor things in the paper edition that says “3 2020” on the title page verso, not mentioned in the book’s errata online:
p. 186 But...
New

Many tasks_proj/tests directories exist in chapters 2, 3, 5 that have tests that use the custom markers smoke and get, which are not decl...
New

Working through the steps (checking that the Info,plist matches exactly), run the demo game and what appears is grey but does not fill th...
New

your book suggests to use Image.toByteData() to convert image to bytes, however I get the following error: "the getter ‘toByteData’ isn’t...
New

When I try the command to create a pair of migration files I get an error.
user=> (create-migration "guestbook")
Execution error (Ill...
New

First, the code resources:
Page 237: rumbl_umbrella/apps/rumbl/mix.exs
Note: That this file is missing.
Page 238: rumbl_umbrella/app...
New

I’m under the impression that when the reader gets to page 136 (“View Data with the Database Inspector”), the code SHOULD be able to buil...
New

Hi,
I am getting an error I cannot figure out on my test.
I have what I think is the exact code from the book, other than I changed “us...
New

Hi all,
currently I wonder how the Tailwind colours work (or don’t work).
For example, in app/views/layouts/application.html.erb I have...
New

From page 13:
On Python 3.7, you can install the libraries with pip by running these commands inside a Python venv using Visual Studio ...
New
Other popular topics

What chair do you have while working… and why?
Is there a ‘best’ type of chair or working position for developers?
New

New

Bought the Moonlander mechanical keyboard. Cherry Brown MX switches. Arms and wrists have been hurting enough that it’s time I did someth...
New

Learn different ways of writing concurrent code in Elixir and increase your application's performance, without sacrificing scalability or...
New

The overengineered Solution to my Pigeon Problem.
TL;DR: I built a wifi-equipped water gun to shoot the pigeons on my balcony, controlle...
New

I have always used antique keyboards like Cherry MX 1800 or Cherry MX 8100 and almost always have modified the switches in some way, like...
New

Author Spotlight:
Tammy Coron
@Paradox927
Gaming, and writing games in particular, is about passion, vision, experience, and immersio...
New

Author Spotlight:
Sophie DeBenedetto
@SophieDeBenedetto
The days of the traditional request-response web application are long gone, b...
New

Will Swifties’ war on AI fakes spark a deepfake porn reckoning?
New

This is cool!
DEEPSEEK-V3 ON M4 MAC: BLAZING FAST INFERENCE ON APPLE SILICON
We just witnessed something incredible: the largest open-s...
New
Categories:
Sub Categories:
Popular Portals
- /elixir
- /rust
- /wasm
- /ruby
- /erlang
- /phoenix
- /keyboards
- /rails
- /js
- /python
- /security
- /go
- /swift
- /vim
- /clojure
- /emacs
- /haskell
- /java
- /onivim
- /svelte
- /typescript
- /crystal
- /c-plus-plus
- /kotlin
- /tailwind
- /gleam
- /ocaml
- /react
- /flutter
- /elm
- /vscode
- /ash
- /opensuse
- /centos
- /php
- /deepseek
- /html
- /zig
- /scala
- /textmate
- /sublime-text
- /nixos
- /debian
- /lisp
- /agda
- /react-native
- /kubuntu
- /arch-linux
- /ubuntu
- /revery
- /spring
- /django
- /manjaro
- /diversity
- /nodejs
- /lua
- /julia
- /c
- /slackware
- /neovim