"withdrawAmount", "expectedResult" ), (10_000, false, 1200, 1199.99, Right(8800.01)), (0, true, 500, 50d, Right(-50)), (1, false, 1200, 1199.99, Left("Insufficient balance to withdraw")), (0, false, 500, 50d, Left("Insufficient balance to withdraw")), (10_000, true, 1200, 1200.0001, Left("Amount exceeding your limit of")), (0, false, 500, 500d, Left("Amount exceeding your limit of")) ) Bank withdrawal – how we would test it in real life ? Use ParameterizedTests -> TableDrivenPropertyChecks Describe test cases Check implementation based on them We can use Properties to help us identify edge cases and add new examples in our table A better approach for this kind of use cases : • Example-based with Table to allow easy addition of new tests cases • Use PBT as a cases finders • Use PBT to check idem potence "withdraw" should "pass examples" in { forAll(`withdraw examples`) { ( balance, isOverdraftAuthorized, maxWithdrawal, withdrawAmount, expectedResult ) => val command = toWithdraw(withdrawAmount) val debitedAccount = AccountService.withdraw( Account(balance, isOverdraftAuthorized, maxWithdrawal), command ) expectedResult match { case Left(expectedErrorMessage) => debitedAccount.left.value should startWith(expectedErrorMessage) case Right(expectedBalance) => debitedAccount.value.balance should be(expectedBalance) debitedAccount.value.withdraws should contain(command) debitedAccount.value.withdraws should have length 1 } } } scala C# java