Stack Exchange network consists of 183 Q&A communities includingStack Overflow, the largest, most trusted online community for developers to learn, share their knowledge, and build their careers.
Visit Stack ExchangeThe first thing I would point out is that currently, you have multiple test cases (or multiple asserts) inside a single test function. A major downside of this is that if any of the asserts fail, the test function will exit immediately and not run the remaining test cases, making locating and debugging failing tests all that bit harder.
There are a couple of approaches to fix this:
Have aseperateseparate test function for each, with the name of the function describing precisely what the test does. I typically follow the format oftest_<subject>_with_<something>_check_<condition>. For example, you could split your current code into 4seperateseparate test functions named:
test_balance_with_debit_equal_to_credit_check_balancedtest_balance_with_debit_greater_than_credit_check_not_balancedtest_balance_with_negative_balance_amounts_check_not_balancedtest_balance_with_small_float_difference_check_not_balancedUse pytest'sparameterize functionality to create sub-tests for us. I personally wouldn't use this approach for the code you have provided, Ifavouritefavour the more explicit result of #1 until we had many more test cases to consider.
As for the global variables, for the size of this, I don't think it's too bad but you might findpytestspytest'sfixtures concept useful in the future. These are useful for employing an Arrange-Act-Assert (AAA) pattern of testing[1][2] and allow you to extract common data or setup to be reused easily.
@pytest.fixturedef cash_account(): return Account(1, "Cash", AccountType.Asset)@pytest.fixturedef mortgage_account(): return Account(2, "Mortgage", AccountType.Asset)@pytest.fixturedef revenue_account(): return Account(3, "Revenues", AccountType.Asset)# name the fixtures you would like to use as parameters to the testdeftest_account_charter_with__check__test_balance_with_debit_equal_to_credit_check_balanced(cash_account, mortgage_account): journal = JournalEntry( [ JournalEntryLeg(cash_account, 50, AmountType.Debit), JournalEntryLeg(cash_account, 50, AmountType.Debit), JournalEntryLeg(mortgage_account, 100, AmountType.Credit), ] ) assert jnl.is_balanced()You can also build fixtures from other fixtures like so:
@pytest.fixturedef account_charter(cash_account, mortgage_account, revenue_account): balance_sheet = AccountRollup([cash_account, mortgage_account]) income_statement = AccountRollup(revenue_account) return AccountRollup([balance_sheet, income_statement]) Thechart_of_accounts variable is unused in the example you provided so I'm not sure if this particular example is relevant but hopefully, you will find a use for the technique elsewhere.
Pytest covers a bit about AAA init'sits fixtures documentation I linked above but I also very much liked these blog posts on the topic:
The first thing I would point out is that currently you have multiple test cases (or multiple asserts) inside a single test function. A major downside of this is that if any of the asserts fail, the test function will exit immediately and not run the remaining test cases, making locating and debugging failing tests all that bit harder.
There are a couple of approaches to fix this:
Have aseperate test function for each, with the name of the function describing precisely what the test does. I typically follow the format oftest_<subject>_with_<something>_check_<condition>. For example you could split your current code into 4seperate test functions named:
test_balance_with_debit_equal_to_credit_check_balancedtest_balance_with_debit_greater_than_credit_check_not_balancedtest_balance_with_negative_balance_amounts_check_not_balancedtest_balance_with_small_float_difference_check_not_balancedUse pytest'sparameterize functionality to create sub-tests for us. I personally wouldn't use this approach for the code you have provided, Ifavourite the more explicit result of #1 until we had many more test cases to consider.
As for the global variables, for the size of this I don't think it's too bad but you might findpytestsfixtures concept useful in the future. These are useful for employing an Arrange-Act-Assert (AAA) pattern of testing[1][2] and allow you to extract common data or setup to be reused easily.
@pytest.fixturedef cash_account(): return Account(1, "Cash", AccountType.Asset)@pytest.fixturedef mortgage_account(): return Account(2, "Mortgage", AccountType.Asset)@pytest.fixturedef revenue_account(): return Account(3, "Revenues", AccountType.Asset)# name the fixtures you would like to use as parameters to the testdeftest_account_charter_with__check__(cash_account, mortgage_account): journal = JournalEntry( [ JournalEntryLeg(cash_account, 50, AmountType.Debit), JournalEntryLeg(cash_account, 50, AmountType.Debit), JournalEntryLeg(mortgage_account, 100, AmountType.Credit), ] ) assert jnl.is_balanced()You can also build fixtures from other fixtures like so:
@pytest.fixturedef account_charter(cash_account, mortgage_account, revenue_account): balance_sheet = AccountRollup([cash_account, mortgage_account]) income_statement = AccountRollup(revenue_account) return AccountRollup([balance_sheet, income_statement]) Thechart_of_accounts variable is unused in the example you provided so I'm not sure if this particular example is relevant but hopefully you will find use for the technique elsewhere.
Pytest covers a bit about AAA init's fixtures documentation I linked above but I also very much liked these blog posts on the topic:
The first thing I would point out is that currently, you have multiple test cases (or multiple asserts) inside a single test function. A major downside of this is that if any of the asserts fail, the test function will exit immediately and not run the remaining test cases, making locating and debugging failing tests all that bit harder.
There are a couple of approaches to fix this:
Have aseparate test function for each, with the name of the function describing precisely what the test does. I typically follow the format oftest_<subject>_with_<something>_check_<condition>. For example, you could split your current code into 4separate test functions named:
test_balance_with_debit_equal_to_credit_check_balancedtest_balance_with_debit_greater_than_credit_check_not_balancedtest_balance_with_negative_balance_amounts_check_not_balancedtest_balance_with_small_float_difference_check_not_balancedUse pytest'sparameterize functionality to create sub-tests for us. I personally wouldn't use this approach for the code you have provided, Ifavour the more explicit result of #1 until we had many more test cases to consider.
As for the global variables, for the size of this, I don't think it's too bad but you might findpytest'sfixtures concept useful in the future. These are useful for employing an Arrange-Act-Assert (AAA) pattern of testing[1][2] and allow you to extract common data or setup to be reused easily.
@pytest.fixturedef cash_account(): return Account(1, "Cash", AccountType.Asset)@pytest.fixturedef mortgage_account(): return Account(2, "Mortgage", AccountType.Asset)@pytest.fixturedef revenue_account(): return Account(3, "Revenues", AccountType.Asset)# name the fixtures you would like to use as parameters to the testdeftest_balance_with_debit_equal_to_credit_check_balanced(cash_account, mortgage_account): journal = JournalEntry( [ JournalEntryLeg(cash_account, 50, AmountType.Debit), JournalEntryLeg(cash_account, 50, AmountType.Debit), JournalEntryLeg(mortgage_account, 100, AmountType.Credit), ] ) assert jnl.is_balanced()You can also build fixtures from other fixtures like so:
@pytest.fixturedef account_charter(cash_account, mortgage_account, revenue_account): balance_sheet = AccountRollup([cash_account, mortgage_account]) income_statement = AccountRollup(revenue_account) return AccountRollup([balance_sheet, income_statement]) Thechart_of_accounts variable is unused in the example you provided so I'm not sure if this particular example is relevant but hopefully, you will find a use for the technique elsewhere.
Pytest covers a bit about AAA inits fixtures documentation I linked above but I also very much liked these blog posts on the topic:
The first thing I would point out is that currently you have multiple test cases (or multiple asserts) inside a single test function. A major downside of this is that if any of the asserts fail, the test function will exit immediately and not run the remaining test cases, making locating and debugging failing tests all that bit harder.
There are a couple of approaches to fix this:
Have a seperate test function for each, with the name of the function describing precisely what the test does. I typically follow the format oftest_<subject>_with_<something>_check_<condition>. For example you could split your current code into 4 seperate test functions named:
test_balance_with_debit_equal_to_credit_check_balancedtest_balance_with_debit_greater_than_credit_check_not_balancedtest_balance_with_negative_balance_amounts_check_not_balancedtest_balance_with_small_float_difference_check_not_balancedUse pytest'sparameterize functionality to create sub-tests for us. I personally wouldn't use this approach for the code you have provided, I favourite the more explicit result of #1 until we had many more test cases to consider.
As for the global variables, for the size of this I don't think it's too bad but you might find pytestsfixtures concept useful in the future. These are useful for employing an Arrange-Act-Assert (AAA) pattern of testing[1][2] and allow you to extract common data or setup to be reused easily.
@pytest.fixturedef cash_account(): return Account(1, "Cash", AccountType.Asset)@pytest.fixturedef mortgage_account(): return Account(2, "Mortgage", AccountType.Asset)@pytest.fixturedef revenue_account(): return Account(3, "Revenues", AccountType.Asset)# name the fixtures you would like to use as parameters to the testdef test_account_charter_with__check__(cash_account, mortgage_account): journal = JournalEntry( [ JournalEntryLeg(cash_account, 50, AmountType.Debit), JournalEntryLeg(cash_account, 50, AmountType.Debit), JournalEntryLeg(mortgage_account, 100, AmountType.Credit), ] ) assert jnl.is_balanced()You can also build fixtures from other fixtures like so:
@pytest.fixturedef account_charter(cash_account, mortgage_account, revenue_account): balance_sheet = AccountRollup([cash_account, mortgage_account]) income_statement = AccountRollup(revenue_account) return AccountRollup([balance_sheet, income_statement])Thechart_of_accounts variable is unused in the example you provided so I'm not sure if this particular example is relevant but hopefully you will find use for the technique elsewhere.
Pytest covers a bit about AAA in it's fixtures documentation I linked above but I also very much liked these blog posts on the topic: