Developing your Tests
What's a Test Case ?
A Test Case is just a Progress 4GL file that follows some simple rules about how to name the internal procedures. The code below shows a simple example of a Test Case file.
/*****
** some code to initialize the environment or
** database before running the test.
*/
PROCEDURE initialize:
END.
/*****
** some code run before every test to reset internal states, if needed.
*/
PROCEDURE setUp:
END.
/*****
** some code run after a test to restore, log or something else.
*/
PROCEDURE tearDown:
END.
/*****
** My First Test. Not that complex but should work fine !
*/
PROCEDURE testMyFirstTest:
RUN assertTrue(TRUE).
END.
/*****
** My Another Test. It starts working fine but fails on second assert !
*/
PROCEDURE testMyAnotherTest:
RUN asserttrue(TRUE).
RUN assertEqualsInt(10, 20).
RUN assertEqualsChar("OK", "OK").
END.
/*****
** My Third Test. Again, the test fails when X equals 7..
*/
PROCEDURE testThirdTest:
DEFINE VARIABLE X AS INTEGER NO-UNDO.
DO X = 1 TO 10000:
RUN assertFalse(X MOD 7 = 0).
END.
RUN fail("This test has failed !").
END.
/*****
** Dispose everything, free resource, close files, disconnect databases, etc.
*/
PROCEDURE dispose:
END.
|
The table below explains all the procedures.
| Procedure | Description |
|---|---|
| initialize | Procedure called by ProUnit before running all the tests in the program. Use it to allocate resources, connect databases of something that is usually time consuming. |
| test<name> | This is where you'll code the logic of your test. You may have many different tests in the same program but all of them must have their name starting by "test" (like testMyFirstTest and testMyAnotherTest). You may have other internal procedures for logic reuse or to make the test more readable but just the test units must start with "test". |
| tearDown | Procedure called by ProUnit after every test. Use it to clean up the environment. |
| dispose | Procedure called by ProUnit to free all resources used by this Test Case (normally allocated by the initialized method). |
Assertions and Failing
During your test you evaluate some conditions to be sure the code you're testing is running fine. For example, suppose you call the Sum method of a persistent object and then check if the returned value matches the value you expected. This is an Assertion. Basically it means: "Here I assume that something is true, or false, or that X equals Y", and if it's not true there is a bug.
ProUnit provides some different assert methods to ease your job:
| Assert Method | Description | Example |
|---|---|---|
| assertTrue | Check if the parameter received is true. If not the test fails. |
RUN AssertTrue(isConnected). |
| assertFalse | Check if the parameter received is FALSE. If not the test fails. |
RUN AssertTrue(AVAILABLE Order). |
| assertEqualsChar | Used to assert that two strings have the same value. |
RUN AssertEqualsChar(cState, "SC"). |
| assertEqualsInt | Used to assert that two integer values have the same value. |
RUN AssertEqualsInt(iCounter, 100). |
| assertEqualsHandle | Used to assert that two handles point to the same program. |
RUN AssertEqualsHandle(hTarget, hW). |
| assertEqualsDate | Used to assert that two dates have the same value. |
RUN AssertEqualsDate(dtTarget, TODAY). |
| assertEqualsDecimal | Used to assert that two decimais values are the same. |
RUN AssertEqualsDecimal(deTarget 10.0). |
| assertEqualsLogical | Used to assert that two logical values are equals. |
RUN AssertEqualsHandle(lValue, true). |
| assertNull | Used to assert that a handle is null. |
RUN AssertNull(hTarget). |
| assertNotNull | Used to assert that a handle points to a valid handle. |
RUN AssertNotNull(hTarget). |
| expectError | Sinalizes that the test expects an error to be raised. |
RUN expectError(YES). |
| expectStop | Sinalizes that a STOP is expected on the test. |
RUN expectStop(YES). |
| expectQuit | Sinalizes that a QUIT is expected on the test. |
RUN expectQuit(YES). |
Failing a Test
Besides using assertions, you can also fail a test using the method fail(String msg). In this case you can pass a string message to help you debugging your code.
