mirror of
https://github.com/EiffelSoftware/eiffel-org.git
synced 2025-12-06 14:52:03 +01:00
Author:Peter Gummer
Date:2009-05-20T15:21:50.000000Z git-svn-id: https://svn.eiffel.com/eiffel-org/trunk@222 abb3cda0-5349-4a8f-a601-0c33ac3a8c38
This commit is contained in:
@@ -203,7 +203,7 @@ Now we click '''OK'''. The dialog disappears and the <code>covers</code> tag:
|
|||||||
<code>
|
<code>
|
||||||
covers/{BANK_ACCOUNT}.deposit
|
covers/{BANK_ACCOUNT}.deposit
|
||||||
</code>
|
</code>
|
||||||
is now visible in the list of tags for the new test we are creating. So, next click '''Create''' and the wizard pane disappears and the Eiffel Testing framework will create our test class and display it in the edit window.
|
is now visible in the list of tags for the new test we are creating. So, next click '''Create''' and the wizard pane disappears and the Eiffel Testing Framework will create our test class and display it in the edit window.
|
||||||
|
|
||||||
|
|
||||||
==Writing a test==
|
==Writing a test==
|
||||||
|
|||||||
@@ -13,11 +13,11 @@ The value of extracted tests is that they provide a kind of a snapshot in testin
|
|||||||
Extracted tests are intended to supplement the suite of manual tests that you have created to do the bulk of your testing. So, usually when you create an extracted test, it happens as a result of your being surprised. You will notice that each time you create an extracted test, you get a new test class, too. This is in contrast to manual tests, in which you might use the wizard to create a new test class and one new test to cover a particular target class and target routine. Then you might manually create, in that same test class, many additional tests covering the routine behavior of the same or other target routines in the same target class.
|
Extracted tests are intended to supplement the suite of manual tests that you have created to do the bulk of your testing. So, usually when you create an extracted test, it happens as a result of your being surprised. You will notice that each time you create an extracted test, you get a new test class, too. This is in contrast to manual tests, in which you might use the wizard to create a new test class and one new test to cover a particular target class and target routine. Then you might manually create, in that same test class, many additional tests covering the routine behavior of the same or other target routines in the same target class.
|
||||||
|
|
||||||
|
|
||||||
==Creating a extracted test==
|
==Creating an extracted test==
|
||||||
|
|
||||||
Let's use the same test system we used for manual tests to demonstrate the creation of an extracted test. The example will be slightly lame because it will find a problem that certainly we would already have discovered had we written a comprehensive set of manual tests against the <code>BANK_ACCOUNT</code> class. Still, the simplicity should help keep things clear.
|
Let's use the same test system we used for manual tests to demonstrate the creation of an extracted test. The example will be slightly lame because it will find a problem that certainly we would already have discovered had we written a comprehensive set of manual tests against the <code>BANK_ACCOUNT</code> class. Still, the simplicity should help keep things clear.
|
||||||
|
|
||||||
If you remember, the root class for the example application, contained no instructions, just a root procedure with no instructions and a declaration <code>my_account</code> of type <code>BANK_ACCOUNT</code>:
|
If you remember, the root class for the example application contained no instructions, just a root procedure with no instructions and a declaration <code>my_account</code> of type <code>BANK_ACCOUNT</code>:
|
||||||
|
|
||||||
|
|
||||||
<code>
|
<code>
|
||||||
@@ -55,7 +55,7 @@ When we look at the feature pane, it's pretty easy to see where the problem is:
|
|||||||
[[Image:Testing Framework extracted 02]]
|
[[Image:Testing Framework extracted 02]]
|
||||||
|
|
||||||
|
|
||||||
There is an error in the specification for <code>withdraw</code>. in the postcondition tagged <code>withdrawn</code>, the plus sign should have been a minus sign. Therefore, the assertion should read like this:
|
There is an error in the specification for <code>withdraw</code>. In the postcondition tagged <code>withdrawn</code>, the plus sign should have been a minus sign. Therefore, the assertion should read like this:
|
||||||
|
|
||||||
<code>
|
<code>
|
||||||
withdrawn: balance = old balance - an_amount
|
withdrawn: balance = old balance - an_amount
|
||||||
@@ -63,7 +63,7 @@ There is an error in the specification for <code>withdraw</code>. in the postcon
|
|||||||
|
|
||||||
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.
|
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:
|
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. <code>TEST_BANK_ACCOUNT_EXTRACTED_WITHDRAW_01</code> should be fairly descriptive. And we'll select the '''tests''' cluster.
|
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. <code>TEST_BANK_ACCOUNT_EXTRACTED_WITHDRAW_01</code> should be fairly descriptive. And we'll select the '''tests''' cluster.
|
||||||
|
|||||||
@@ -107,6 +107,7 @@ Next you fix the problems that the compiler discovered. The compiler errors conc
|
|||||||
|
|
||||||
Let's look at some specific cases and how fixing them unfolds.
|
Let's look at some specific cases and how fixing them unfolds.
|
||||||
|
|
||||||
|
===Variables not properly set===
|
||||||
|
|
||||||
[[Image:VoidSafeVEVI1]]
|
[[Image:VoidSafeVEVI1]]
|
||||||
|
|
||||||
@@ -144,7 +145,7 @@ Here attribute declarations for <code>my_nvp</code> and <code>my_nvp_list</code>
|
|||||||
</code>
|
</code>
|
||||||
|
|
||||||
|
|
||||||
In second case, there is also an Initialization rule violation (VEVI), this time on <code>Result</code>, in this routine:
|
In a second case, there is also an Initialization rule violation (VEVI), this time on <code>Result</code>, in this routine:
|
||||||
|
|
||||||
<code>
|
<code>
|
||||||
at_first (nm: STRING): NVP is
|
at_first (nm: STRING): NVP is
|
||||||
@@ -178,9 +179,11 @@ So the least impact to this routine will be to declare its type as <code>detacha
|
|||||||
</code>
|
</code>
|
||||||
|
|
||||||
|
|
||||||
The same change is made in other routines that can return void by design.
|
The same change is made in other routines that can return void by design, particularly including a routine called <code>value_at_first</code>, which gets our attention next.
|
||||||
|
|
||||||
The change to <code>at_first</code> satisfies the VEVI issue in <code>at_first</code>, but it introduces a previously unseen conformance issue (VJAR) in a routine <code>value_at_first</code>:
|
===Source of assignment does not conform to target===
|
||||||
|
|
||||||
|
The change to <code>at_first</code> satisfies the VEVI issue in <code>at_first</code>, but it introduces a previously unseen conformance issue (VJAR) in the routine <code>value_at_first</code>:
|
||||||
|
|
||||||
|
|
||||||
[[Image:VoidSafeVJAR1]]
|
[[Image:VoidSafeVJAR1]]
|
||||||
@@ -226,6 +229,10 @@ Here the '''attached syntax''' can fix the problem and streamline the routine:
|
|||||||
|
|
||||||
In this version <code>tn</code> need not be declared as a local variable. Remember that the attached syntax provides a fresh local variable, if the expression is not void.
|
In this version <code>tn</code> need not be declared as a local variable. Remember that the attached syntax provides a fresh local variable, if the expression is not void.
|
||||||
|
|
||||||
|
===Both VEVI and VJAR errors===
|
||||||
|
|
||||||
|
A design issue in class <code>NVP_LIST</code> causes issues of both conformance and initialization. In the original design, an instance of the class NVP_LIST could traverse its contents NVP-by-NVP with inherited functionality. But it also could traverse its contents returning "sublists" based on recurring patterns of the <code>name</code> attributes of a sequence of name/value pairs.
|
||||||
|
|
||||||
|
|
||||||
==Code patterns==
|
==Code patterns==
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user