M
Matt Baker
Guest
I think you’ll find that writing unit tests is going to require a bit of framework in your environment. Typically anything beyond a few simple tests is going to require some bootstrap framework that is convenience to access for developers and can be automated. The framework is going to consist of some configuration elements along with some code to get that into your unit tests. Generally something like some continuous integration product like TeamCity or Jenkins that can pick up any new tests and run them automatically on a schedule is really useful…but not at all required. But even if you are not using a CA tool you can make a few things consistent and reproducible without much work. Consider wrapping your tests in an ant build.xml script, and you can call them directly from a CA tool or launch them directly from within PDSOE (PDSOE ships functionality to edit and run ant build.xml scripts), or you can run the test by itself from within PDSOE. Keep the ant scripts with your unit tests as they are part of the code base. This way developers can find and execute them conveniently. Part of that consistency step in your framework is abstracting any variable information like port numbers, machine names, database names and such out to configuration files where it can be generated by a script or by hand and easily adjusted for new environments. Don’t pass varying information into the test via parameters. Each test should test one thing. Simple properties files that can be read in using a temp-table or a simple import statement and static variables that can be accessed directly your unit tests can make things convenient for adjusting them. This is where “setup” and “teardown” come into play. You want to keep your setup methods very simple so if something changes you don’t have to rework much. They are there for convenience of the test, but they are not part of the test itself. Consider abstracting out things like loading property files, connecting to databases and appservers and such (unless those are the point of the test) to singular spots in your test code framework and not replicating that into each test. Have a testing project as Sanjeev suggested in PDSOE that hosts the testing related framework code and the unit tests together lets you keep all this together. Make this project build and run just like your project would in your scheduled builds. If it is easy to run then you can get into the habit of running it to test code instead of running the debugger. OO languages don’t allow have a “main block”. But ABLUnit allows either .p or .cls based tests. Try to keep any executable code (run statement ands o on) inside the annotated test, setup, or teardown methods. This allows the framework more control over what gets executed and in what order. With a unit test, behavior outside the scope of the testing method is “undefined”, you can avoid this by not using the main block for anything beyond variable definitions. If you’re comfortable with OO code, write your unit tests using .cls files and you’ll avoid doing this by accident. Sorry for the word wall L Unit testing has been raised to an art form and there can be a huge number of things to consider. mattB From: TrueDon [mailto:bounce-TrueDon@community.progress.com] Sent: Thursday, May 28, 2015 2:13 PM To: TU.OE.Development@community.progress.com Subject: RE: [Technical Users - OE Development] ABL Unit Test case in a called .p RE: ABL Unit Test case in a called .p Reply by TrueDon Thanks for the reply Sanjeev, I"m going to take your advice on seperating code from unit tests. I'm trying to see how I can use the ABL unit testing in our existing code. In some cases we want to add a test case to an existing .p with an input parameter so it is the other way around where I want to keep the parameter in that procedure and be able to run the test case using the @TestSuite annotation so it doesn't cause the run-time error showing up in the results; because the ABLunit is looking at the input parameter that is outside the Life cycle methods you mentioned. Also following up on what you mentioned that the ABLUnit only considers code inside life cycle methods(@Before, @After, @Setup, @TearDown) and Test methods(@Test) but in my example above the "RUN stringcat" gets called outside of any Testing annotation when I run the ABL Unit, the code in the entire procedure gets run, some times multiple times. If I run the below code I get the following messages, "xxx" "IN HERE" "xxx" "IN HERE" "setup" "xxx" "IN HERE" "setup". Should the two 'xxx' and any 'IN HERE' messages have been displayed since that code is outside any @ annotations? USING OpenEdge.Core.Assert. BLOCK-LEVEL ON ERROR UNDO, THROW. DEFINE VARIABLE vout AS CHARACTER NO-UNDO. DEFINE VARIABLE vhere AS CHARACTER NO-UNDO. @Setup. PROCEDURE Setup: MESSAGE "setup" VIEW-AS ALERT-BOX. END. RUN runproc(OUTPUT vout). vhere = "IN HERE". MESSAGE vhere VIEW-AS ALERT-BOX. @Test. PROCEDURE testcase1: ASSERT:Equals("aaa","bbb"). END. @Test. PROCEDURE testcase2: ASSERT:Equals(vout,"xxx"). END. PROCEDURE runproc: DEFINE OUTPUT PARAMETER pout AS CHARACTER NO-UNDO. pout = "xxx". MESSAGE pout VIEW-AS ALERT-BOX. END. Stop receiving emails on this subject. Flag this post as spam/abuse.
Continue reading...
Continue reading...