Publicidade - Adsense

Testing on the Toilet: Keep Tests Focused


  • Moderador

    This article was adapted from a Google Testing on the Toilet (TotT) episode. You can download a printer-friendly version of this TotT episode and post it in your office.
    By Ben Yu

    What scenario does the following code test?

    <table class=“my-bordered-table” style=“width: 613px;”>

    <thead>

    <tr>

    <td style=“background-color: #cfe2f3; vertical-align: top; width: 607px;”>

    <pre style=“background-color: #cfe2f3; border: 0px; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-top: 0px;”>TEST_F(BankAccountTest, WithdrawFromAccount) {
    Transaction transaction = account_.Deposit(Usd(5));
    clock_.AdvanceTime(MIN_TIME_TO_SETTLE);
    account_.Settle(transaction);

    EXPECT_THAT(account_.Withdraw(Usd(5)), IsOk());
    EXPECT_THAT(account_.Withdraw(Usd(1)), IsRejected());
    account_.SetOverdraftLimit(Usd(1));
    EXPECT_THAT(ccount_.Withdraw(Usd(1)), IsOk());
    }</pre>

    </td>

    </tr>

    </thead>

    </table>

    Translated to English: “(1) I had $5 and was able to withdraw $5; (2) then got rejected when overdrawing $1; (3) but if I enable overdraft with a $1 limit, I can withdraw $1.” If that sounds a little hard to track, it is: it is testing three scenarios, not one.

    A better approach is to exercise each scenario in its own test:

    <table class=“my-bordered-table” style=“width: 613px;”>

    <thead>

    <tr>

    <td style=“background-color: #d9ead3; vertical-align: top; width: 607px;”>

    <pre style=“background-color: #d9ead3; border: 0px; color: black; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-top: 0px;”>TEST_F(BankAccountTest, CanWithdrawWithinBalance) {
    DepositAndSettle(Usd(5)); // Common setup code is extracted into a helper method.
    EXPECT_THAT(account_.Withdraw(Usd(5)), IsOk());
    }
    TEST_F(BankAccountTest, CannotOverdraw) {
    DepositAndSettle(Usd(5));
    EXPECT_THAT(account_.Withdraw(Usd(6)), IsRejected());
    }
    TEST_F(BankAccountTest, CanOverdrawUpToOverdraftLimit) {
    DepositAndSettle(Usd(5));
    account_.SetOverdraftLimit(Usd(1));
    EXPECT_THAT(account_.Withdraw(Usd(6)), IsOk());
    }</pre>

    </td>

    </tr>

    </thead>

    </table>

    Writing tests this way provides many benefits:

    • Logic is easier to understand because there is less code to read in each test method.

    • Setup code in each test is simpler because it only needs to serve a single scenario.

    • Side effects of one scenario will not accidentally invalidate or mask a later scenario’s assumptions.

    • If a scenario in one test fails, other scenarios will still run since they are unaffected by the failure.

    • Test names clearly describe each scenario, which makes it easier to learn which scenarios exist.

    One sign that you might be testing more than one scenario: after asserting the output of one call to the system under test, the test makes another call to the system under test.

    While a scenario for a unit test often consists of a single call to the system under test, its scope can be larger for integration and end-to-end tests. For example, a test that a web UI can send email might open the inbox, click the compose button, write some text, and press the send button.


 

Publicidade - Adsense

status at

26
Online

2.9k
Usuários

1.7k
Tópicos

5.7k
Posts

});