From 4a65e7a0087cdda90f2f0ace5c0bd8ef20ccbf39 Mon Sep 17 00:00:00 2001 From: halw Date: Thu, 19 Feb 2009 21:16:25 +0000 Subject: [PATCH] Author:halw Date:2009-02-19T21:16:25.000000Z git-svn-id: https://svn.eiffel.com/eiffel-org/trunk@188 abb3cda0-5349-4a8f-a601-0c33ac3a8c38 --- .../using-autotest/using-extracted-tests.wiki | 124 +++++++++++++++++- 1 file changed, 122 insertions(+), 2 deletions(-) diff --git a/documentation/current/eiffelstudio/eiffelstudio-guided-tour/using-autotest/using-extracted-tests.wiki b/documentation/current/eiffelstudio/eiffelstudio-guided-tour/using-autotest/using-extracted-tests.wiki index 5698f85d..63ad0f5e 100644 --- a/documentation/current/eiffelstudio/eiffelstudio-guided-tour/using-autotest/using-extracted-tests.wiki +++ b/documentation/current/eiffelstudio/eiffelstudio-guided-tour/using-autotest/using-extracted-tests.wiki @@ -4,8 +4,128 @@ {{underconstruction}} -When you are running a system in EiffelStudio debugger, you can ask the Eiffel Testing Framework to extract a new test class and test from the current executable context. Most often you would use this capability in the case in which you experienced an unexpected failure or exception in one of your routines. It is possible, though, to extract at any point at which the system is paused. +==About extracted tests== -The great advantage to extracted tests is that they provide a kind of a snapshot in testing form that will reproduce the unexpected failure. +When you are running a system in EiffelStudio debugger and whenever your system is paused, you can ask the Eiffel Testing Framework to extract a new test class and test from the current executable context. Most often you would use this capability in the case in which you experienced an unexpected failure or exception in one of your routines. It is possible, though, to extract at any point at which the system is paused. + +The value of extracted tests is that they provide a kind of a snapshot in testing form that will reproduce the unexpected failure. An extracted test attempts to reproduce the context in which the offending routine executed. So, extracted tests supplement your manual tests. They serve to cover situations which you just may not have written manual tests to cover. + + +==Creating a extracted test== + +Let's use the same test system we used for manual tests to demonstrate the creation of an extracted test. + +If you remember, the root class for the example application, contained no instructions, just a root procedure with no instructions and a declaration my_account of type BANK_ACCOUNT: + + + + make + -- Run application. + do + end + + my_account: BANK_ACCOUNT + + + +Now, let's add some code into the make procedure that will make use of my_account: + + + make + -- Run application. + do + create my_account + my_account.deposit (500) + my_account.withdraw (100) + end + + + +If we run the application from EiffelStudio, we see that it stops when it incurs a postcondition violation in {BANK_ACCOUNT}.withdraw: + + +[[Image:Testing Framework extracted 01]] + + +When we look at the feature pane, it's pretty easy to see where the problem is: + + +[[Image:Testing Framework extracted 02]] + + +There is an error in the specification for withdraw. in the postcondition tagged withdrawn, the plus sign should have been a minus sign. Therefore, the assertion should read like this: + + + withdrawn: balance = old balance - an_amount + + +Certainly we will fix this, but the Eiffel Testing Framework gives us the opportunity to extract a test based on this particular failure. So, let's do that. + +So, we go to the Eiffel Testing Framework interface and click the ''Create new tests'' button to request the ''New Eiffel test wizard''. Because we are paused in the debugger, the test wizard appears with the '''Extract tests from running application''' radio button already checked: + + +When we click next, we are presented with the same ''New test class'' pane that we saw with manual tests. We can give the test class a name. TEST_BANK_ACCOUNT_EXTRACTED_WITHDRAW_01 should be unique. And we'll select the '''tests''' cluster. + +When we click next, we are presented with a wizard pane that shows a depiction of the current call stack and asks us for which feature(s) on the stack we want to create the test: + +[[Image:New test wizard screen 03E 01]] + + +The choice for withdraw is the selection we want, so we just click next. The Testing Framework creates the new test and returns us to the debugger, where our system is still on hold. We can stop execution and compile to include the new test. + +Now we see the new test class and test in the Testing Framework's interface windows. If we run our tests we see that the test on withdraw is still failing: + +[[Image:Testing Framework interface after run 04]] + +If we fix the error in the postcondition in withdraw and re-execute the test, we find it successful. + + +==A closer look at an extracted test== + +Look at the code that got generated for the extracted test after the assertion violation occurred: + + +note + description: "Regression tests reproducing application state of a previous execution." + author: "Testing tool" + +class + TEST_BANK_ACCOUNT_EXTRACTED_WITHDRAW_01 + +inherit + EQA_EXTRACTED_TEST_SET + +feature -- Test routines + + test_withdraw + note + testing: "type/extracted" + testing: "covers/{BANK_ACCOUNT}.withdraw" + do + run_extracted_test (agent {BANK_ACCOUNT}.withdraw, ["#1", {INTEGER_32} 100]) + end + +feature {NONE} -- Access + + context: !ARRAY [!TUPLE [type: !TYPE [ANY]; attributes: !TUPLE; inv: BOOLEAN]] + -- + do + Result := << + [{BANK_ACCOUNT}, [ + "balance", {INTEGER_32} 400 + ], False] + >> + end + +end + + +You have probably noticed that it doesn't look much like the code that we wrote for our manual test in the previous section. + +There are some items of interest here that are worth mentioning. One is that the class does not inherit directly from EQA_TEST_SET as our manual test did. Instead, it inherits from EQA_EXTRACTED_TEST_SET which descends from EQA_TEST_SET. EQA_EXTRACTED_TEST_SET provides additional functionality for extracted tests. + +Secondly, notice that the call to the target routine {BANK_ACCOUNT}.withdraw is effected in the routine test_withdraw which passes an agent representing {BANK_ACCOUNT}.withdraw to the procedure run_extracted_test. The second argument to run_extracted_test is a TUPLE with the argument values which were used in the call to withdraw which caused the original assertion violation. + +A third thing to notice is the function context. This is how the Eiffel Testing Framework recreates the state of the instance of BANK_ACCOUNT at the time of the assertion violation.