Skip to content

Commit ade5f68

Browse files
committed
Fix failing tests and use 1559 defaults for test params
- Fixed tests that were failing from the implementation of the new EIP-1559 fields (maxFeePerGas and maxPriorityFeePerGas). Updated most of our existing tests to use these new fields in order to encourage their use / be updated to the new standard. - Updated documentation around unit and integration testing and how to contribute to our test suite.
1 parent 7f1b8d7 commit ade5f68

File tree

9 files changed

+291
-103
lines changed

9 files changed

+291
-103
lines changed

docs/contributing.rst

Lines changed: 82 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ with the exception of ``self`` and ``cls`` as seen in the following example.
126126
self.reset()
127127
128128
129-
Running the tests
129+
Running The Tests
130130
~~~~~~~~~~~~~~~~~
131131

132132
A great way to explore the code base is to run the tests.
@@ -136,7 +136,7 @@ First, install the test dependencies:
136136

137137
.. code:: sh
138138
139-
$ pip install -e ".[test]"
139+
$ pip install -e ".[tester]"
140140
141141
You can run all tests with:
142142

@@ -173,6 +173,73 @@ suite as part of the CI check. This test suite will run in the CI anytime a
173173
pull request is opened or updated.
174174

175175

176+
Writing Tests
177+
~~~~~~~~~~~~~
178+
179+
We strongly encourage contributors to write good tests for their code as
180+
part of the code review process. This helps ensure that your code is doing
181+
what it should be doing.
182+
183+
We strongly encourage you to use our existing tests for both guidance and
184+
homogeneity / consistency across our tests. We use ``pytest`` for our tests.
185+
For more specific pytest guidance, please refer to the `pytest documentation`_.
186+
187+
Within the ``pytest`` scope, :file:`conftest.py` files are used for common code
188+
shared between modules that exist within the same directory as that particular
189+
:file:`conftest.py` file.
190+
191+
Unit Testing
192+
^^^^^^^^^^^^
193+
194+
Unit tests are meant to test the logic of smaller chunks (or units) of the
195+
codebase without having to be wired up to a client. Most of the time this
196+
means testing selected methods on their own. They are meant to test the logic
197+
of your code and make sure that you get expected outputs out of selected inputs.
198+
199+
Our unit tests live under appropriately named child directories within the
200+
``/tests`` directory. The core of the unit tests live under ``/tests/core``.
201+
Do your best to follow the existing structure when choosing where to add
202+
your unit test.
203+
204+
Integration Testing
205+
^^^^^^^^^^^^^^^^^^^
206+
207+
Our integration test suite setup lives under the ``/tests/integration`` directory.
208+
The integration test suite is dependent on what we call "fixtures" (not to be
209+
confused with pytest fixtures). These zip file fixtures, which also live in the
210+
``/tests/integration`` directory, are configured to run the specific client we are
211+
testing against along with a genesis configuration that gives our tests some
212+
pre-determined useful objects (like unlocked, pre-loaded accounts) to be able to
213+
interact with the client and run our tests.
214+
215+
Though the setup lives in ``/tests/integration``, our integration module tests are
216+
written across different files within ``/web3/_utils/module_testing``. The tests
217+
are written there but run configurations exist across the different files within
218+
``/tests/integration/``. The parent ``/integration`` directory houses some common
219+
configuration shared across all client tests, whereas the ``/go_ethereum`` and
220+
``/parity`` directories house common code to be shared among each respective client
221+
tests.
222+
223+
* :file:`common.py` files within the client directories contain code that is shared across
224+
all provider tests (http, ipc, and ws). This is mostly used to override tests that span
225+
across all providers.
226+
* :file:`conftest.py` files within each of these directories contain mostly code that can
227+
be *used* by all test files that exist within the same directory as the :file:`conftest.py`
228+
file. This is mostly used to house pytest fixtures to be shared among our tests. Refer to
229+
the `pytest documentation on fixtures`_ for more information.
230+
* :file:`test_{client}_{provider}.py` (e.g. :file:`test_goethereum_http.py`) files are where
231+
client-and-provider-specific test configurations exist. This is mostly used to override tests
232+
specific to the provider type for the respective client.
233+
234+
Sometimes the client may be bogged down with pending transactions or anything else that may
235+
interfere with your particular test. In this case, it may be useful to run your test at the
236+
front of the test suite. If you feel it makes sense to run a particular test at a specific
237+
position in the test suite, there is a handy ``pytest`` hook that allows us to somewhat
238+
customize the order of our integration tests. This ``pytest_collection_modifyitems`` hook
239+
can be defined within the appropriate ``conftest.py`` file, depending on the scope of the
240+
test suite you want it to affect.
241+
242+
176243
Manual Testing
177244
~~~~~~~~~~~~~~
178245

@@ -217,7 +284,7 @@ If possible, the change to the release notes file should be included in the
217284
commit that introduces the feature or bugfix.
218285

219286

220-
Generating new fixtures
287+
Generating New Fixtures
221288
~~~~~~~~~~~~~~~~~~~~~~~
222289

223290
Our integration tests make use of Geth and Parity/OpenEthereum private networks.
@@ -228,7 +295,7 @@ Before generating new fixtures, make sure you have the test dependencies install
228295

229296
.. code:: sh
230297
231-
$ pip install -e ".[test]"
298+
$ pip install -e ".[tester]"
232299
233300
.. note::
234301

@@ -237,7 +304,7 @@ Before generating new fixtures, make sure you have the test dependencies install
237304
testing Web3.py functionality against.
238305

239306

240-
Geth fixtures
307+
Geth Fixtures
241308
^^^^^^^^^^^^^
242309

243310
1. Install the desired Geth version on your machine locally. We recommend `py-geth`_ for
@@ -265,7 +332,7 @@ Geth fixtures
265332
you may again include the ``GETH_BINARY`` environment variable.
266333

267334

268-
CI testing with a nightly Geth build
335+
CI Testing With a Nightly Geth Build
269336
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
270337

271338
Occasionally you'll want to have CI run the test suite against an unreleased version of Geth,
@@ -291,7 +358,7 @@ an unstable client.
291358
6. Create a PR and let CI do its thing.
292359

293360

294-
Parity/OpenEthereum fixtures
361+
Parity/OpenEthereum Fixtures
295362
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
296363

297364
1. The most reliable way to get a specific Parity/OE binary is to download
@@ -323,7 +390,7 @@ Parity/OpenEthereum fixtures
323390
Releasing
324391
~~~~~~~~~
325392

326-
Final test before each release
393+
Final Test Before Each Release
327394
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
328395

329396
Before releasing a new version, build and test the package that will be released.
@@ -349,7 +416,7 @@ virtualenv for smoke testing:
349416
>>> ...
350417
351418
352-
Verify the latest documentation
419+
Verify The Latest Documentation
353420
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
354421

355422
To preview the documentation that will get published:
@@ -359,15 +426,15 @@ To preview the documentation that will get published:
359426
$ make docs
360427
361428
362-
Preview the release notes
429+
Preview The Release Notes
363430
^^^^^^^^^^^^^^^^^^^^^^^^^
364431

365432
.. code:: sh
366433
367434
$ towncrier --draft
368435
369436
370-
Compile the release notes
437+
Compile The Release Notes
371438
^^^^^^^^^^^^^^^^^^^^^^^^^
372439

373440
After confirming that the release package looks okay, compile the release notes:
@@ -381,7 +448,7 @@ You may need to fix up any broken release note fragments before committing. Keep
381448
running ``make build-docs`` until it passes, then commit and carry on.
382449

383450

384-
Push the release to GitHub & PyPI
451+
Push The Release to GitHub & PyPI
385452
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
386453

387454
After committing the compiled release notes and pushing them to the master
@@ -392,7 +459,7 @@ branch, release a new version:
392459
$ make release bump=$$VERSION_PART_TO_BUMP$$
393460
394461
395-
Which version part to bump
462+
Which Version Part to Bump
396463
^^^^^^^^^^^^^^^^^^^^^^^^^^
397464

398465
The version format for this repo is ``{major}.{minor}.{patch}`` for
@@ -418,3 +485,5 @@ version explicitly, like ``make release bump="--new-version 4.0.0-alpha.1 devnum
418485
.. _py-geth: https://github.com/ethereum/py-geth
419486
.. _Github releases: https://github.com/openethereum/openethereum/releases
420487
.. _Build the binary: https://github.com/openethereum/openethereum/#3-building-
488+
.. _pytest documentation: https://docs.pytest.org/en/latest
489+
.. _pytest documentation on fixtures: https://docs.pytest.org/en/latest/how-to/fixtures.html

newsfragments/2053.bugfix.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix broken tests and use the new 1559 params for most of our test transactions.

newsfragments/2053.doc.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Added general documentation on unit and integration testing and how to contribute to our test suite.

tests/integration/conftest.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,30 @@
1515
)
1616

1717

18+
def pytest_collection_modifyitems(items):
19+
"""
20+
Certain tests have issues running after most of our test suite has run. If we run
21+
these tests in the beginning, we can ensure that the client isn't overloaded with
22+
context from our other tests and therefore reduce the noise for these more sensitive
23+
tests. We can somewhat control when tests are run by overriding this pytest hook and
24+
customizing the test order. You may find it helpful to move a conflicting test to
25+
the beginning of the test suite or configure the test order in some other way here.
26+
"""
27+
test_names_to_append_to_start = [
28+
'test_eth_get_logs_with_logs',
29+
'test_eth_call_old_contract_state',
30+
]
31+
for index, item in enumerate(items):
32+
# We run two versions of some tests that end with [<lambda>] or [address_conversion_func1].
33+
# This step cleans up the name depending on whether or not they exist as two separate
34+
# tests or just one without the bracketed "[]" suffix.
35+
test_name = item.name if "[" not in item.name else item.name[:item.name.find("[")]
36+
37+
if test_name in test_names_to_append_to_start:
38+
test_item = items.pop(index)
39+
items.insert(0, test_item)
40+
41+
1842
@pytest.fixture(scope="module")
1943
def math_contract_factory(web3):
2044
contract_factory = web3.eth.contract(abi=MATH_ABI, bytecode=MATH_BYTECODE)

tests/integration/go_ethereum/common.py

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
# from concurrent.futures._base import (
2-
# TimeoutError as FuturesTimeoutError,
3-
# )
41
import pytest
52

63
from web3._utils.module_testing import ( # noqa: F401
@@ -20,20 +17,16 @@ def _check_web3_clientVersion(self, client_version):
2017

2118

2219
class GoEthereumEthModuleTest(EthModuleTest):
23-
# @pytest.mark.xfail(
24-
# strict=False,
25-
# raises=FuturesTimeoutError,
26-
# reason='Sometimes a TimeoutError is hit when waiting for the txn to be mined',
27-
# )
28-
@pytest.mark.skip(reason="London TODO: crashes on [address_conversion_func1]")
20+
@pytest.mark.xfail(
21+
strict=False,
22+
reason='Sometimes a TimeoutError is hit when waiting for the txn to be mined',
23+
)
2924
def test_eth_replace_transaction_already_mined(self, web3, unlocked_account_dual_type):
30-
web3.geth.miner.start()
31-
super().test_eth_replace_transaction_already_mined(web3, unlocked_account_dual_type)
32-
web3.geth.miner.stop()
33-
34-
@pytest.mark.skip(reason="London TODO: pending call isn't found")
35-
def test_eth_call_old_contract_state(self, web3, math_contract, unlocked_account):
36-
super().test_eth_call_old_contract_state(web3, math_contract, unlocked_account)
25+
try:
26+
web3.geth.miner.start()
27+
super().test_eth_replace_transaction_already_mined(web3, unlocked_account_dual_type)
28+
finally:
29+
web3.geth.miner.stop()
3730

3831
@pytest.mark.xfail(reason='eth_signTypedData has not been released in geth')
3932
def test_eth_sign_typed_data(self, web3, unlocked_account_dual_type):

tests/integration/test_ethereum_tester.py

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -272,18 +272,34 @@ def test_eth_getBlockByHash_pending(
272272
assert block['hash'] is not None
273273

274274
@disable_auto_mine
275+
@pytest.mark.xfail(reason='EIP 1559 is not implemented on eth-tester')
275276
def test_eth_get_transaction_receipt_unmined(self, eth_tester, web3, unlocked_account):
276277
super().test_eth_get_transaction_receipt_unmined(web3, unlocked_account)
277278

278279
@disable_auto_mine
279-
def test_eth_replaceTransaction_deprecated(self, eth_tester, web3, unlocked_account):
280-
super().test_eth_replaceTransaction_deprecated(web3, unlocked_account)
280+
def test_eth_replace_transaction_legacy(self, eth_tester, web3, unlocked_account):
281+
super().test_eth_replace_transaction_legacy(web3, unlocked_account)
281282

282283
@disable_auto_mine
284+
@pytest.mark.xfail(reason='EIP 1559 is not implemented on eth-tester')
283285
def test_eth_replace_transaction(self, eth_tester, web3, unlocked_account):
284286
super().test_eth_replace_transaction(web3, unlocked_account)
285287

288+
@pytest.mark.xfail(reason='EIP 1559 is not implemented on eth-tester')
289+
def test_eth_replace_transaction_underpriced(self, web3, emitter_contract_address):
290+
super().test_eth_replace_transaction_underpriced(web3, emitter_contract_address)
291+
292+
@disable_auto_mine
293+
@pytest.mark.xfail(reason='EIP 1559 is not implemented on eth-tester')
294+
def test_eth_replaceTransaction_deprecated(self, eth_tester, web3, unlocked_account):
295+
super().test_eth_replaceTransaction_deprecated(web3, unlocked_account)
296+
297+
@pytest.mark.xfail(reason='EIP 1559 is not implemented on eth-tester')
298+
def test_eth_replace_transaction_already_mined(self, web3, emitter_contract_address):
299+
super().test_eth_replace_transaction_already_mined(web3, emitter_contract_address)
300+
286301
@disable_auto_mine
302+
@pytest.mark.xfail(reason='EIP 1559 is not implemented on eth-tester')
287303
def test_eth_replace_transaction_incorrect_nonce(self, eth_tester, web3, unlocked_account):
288304
super().test_eth_replace_transaction_incorrect_nonce(web3, unlocked_account)
289305

@@ -429,24 +445,32 @@ def test_eth_estimate_gas_revert_without_msg(self, web3, revert_contract, unlock
429445
web3.eth.estimate_gas(txn_params)
430446

431447
@pytest.mark.xfail(reason='EIP 1559 is not implemented on eth-tester')
432-
def test_1559_default_fees(self, web3, emitter_contract_address):
433-
super().test_1559_default_fees(web3, emitter_contract_address)
448+
def test_eth_send_transaction(self, web3, emitter_contract_address):
449+
super().test_eth_send_transaction(web3, emitter_contract_address)
450+
451+
@pytest.mark.xfail(reason='EIP 1559 is not implemented on eth-tester')
452+
def test_eth_sendTransaction_deprecated(self, web3, emitter_contract_address):
453+
super().test_eth_sendTransaction_deprecated(web3, emitter_contract_address)
454+
455+
@pytest.mark.xfail(reason='EIP 1559 is not implemented on eth-tester')
456+
def test_eth_send_transaction_with_nonce(self, web3, emitter_contract_address):
457+
super().test_eth_send_transaction_with_nonce(web3, emitter_contract_address)
434458

435459
@pytest.mark.xfail(reason='EIP 1559 is not implemented on eth-tester')
436-
def test_1559_canonical(self, web3, emitter_contract_address):
437-
super().test_1559_canonical(web3, emitter_contract_address)
460+
def test_eth_send_transaction_default_fees(self, web3, emitter_contract_address):
461+
super().test_eth_send_transaction_default_fees(web3, emitter_contract_address)
438462

439463
@pytest.mark.xfail(reason='EIP 1559 is not implemented on eth-tester')
440-
def test_1559_hex_fees(self, web3, emitter_contract_address):
441-
super().test_1559_hex_fees(web3, emitter_contract_address)
464+
def test_eth_send_transaction_hex_fees(self, web3, emitter_contract_address):
465+
super().test_eth_send_transaction_hex_fees(web3, emitter_contract_address)
442466

443467
@pytest.mark.xfail(reason='EIP 1559 is not implemented on eth-tester')
444-
def test_1559_no_gas(self, web3, emitter_contract_address):
445-
super().test_1559_no_gas(web3, emitter_contract_address)
468+
def test_eth_send_transaction_no_gas(self, web3, emitter_contract_address):
469+
super().test_eth_send_transaction_no_gas(web3, emitter_contract_address)
446470

447471
@pytest.mark.xfail(reason='EIP 1559 is not implemented on eth-tester')
448-
def test_1559_no_max_fee(self, web3, emitter_contract_address):
449-
super().test_1559_no_max_fee(web3, emitter_contract_address)
472+
def test_eth_send_transaction_no_max_fee(self, web3, emitter_contract_address):
473+
super().test_eth_send_transaction_no_max_fee(web3, emitter_contract_address)
450474

451475

452476
class TestEthereumTesterVersionModule(VersionModuleTest):

0 commit comments

Comments
 (0)