1 — Debugging and testing support
Now that we are familiar with erlang and able to create a module, we can start looking into erlangs debugger. The monitor window will display when you call,
debugger:start().
In the erlang terminal. Then select
Module > Interpret… and select the appropriate module.
To view the contents of the source file you select
Module > module to be interpreted > View
Now you can set breakpoints in the source code. The breakpoints can only be set at an executable line. A blank line, line containing comment, function head, or pattern in a case or receive statement is not executable. The trigger action allows you to enable, disable, or delete breakpoints. You can set a line break, conditional break, or a function break.
Line Breakpoint:
A line break can be set by selecting,
Break > Line Break…
A popup menu will appear allowing you to select the module, enter the breakpoint line number, and selecting the trigger action.
Conditional Breakpoint:
A conditonal breakpoint can be set by selecting,
Break > Conditional Break…
A popup menu will appear allowing you to select the module, breakpoint line number, specifying the CModule and CFunction, and trigger action. The condition is specified as a module name CModule and function name CFunction. When the process reaches the breakpoint, CModule:CFunction(Binding) is evaluated. If the function returns true the process stops and if the function returns false the breakpoint is ignored. Binding is a list of variable bindings and the variable can be retrieved by using the fuction int:get_binding(Variable, Bindings).
Function Breakpoint:
To set a function breakpoint select,
Break > Function Break…
The popup menu will appear allowing you select the module and function. A function breakpoint is a set of line breakpoints, one at the first line of the specified function.
2 — Demonstration of debugger
3 — Unit testing framework
EUnit — a Lightweight Unit Testing Framework for Erlang
Being able to test small portions or ‘units’ of your program is extremely useful in optimizing your code, and the time you spend writing it. EUnit is the Erlang specific unit testing framework which builds on other object-oriented language unit testing frameworks. We will give you an introduction to EUnit and some examples of its use.
Getting Started with EUnit:
To use EUnit in your module, simply add the header
in your module directly after its declaration. This will create an exported function test(), cause all functions whose names match …_test()(test function) or …_test_() (test generator function) to be automatically exported from the module, and makes all the preprocessor macros of EUnit available to help in writing tests.
Writing Test Functions:
A simple test function recognized by EUnit is anyone with a name ending in …_test() which takes no arguments and when executed it will either succeed or throw an exception. And example of what this code might look like would be
Which one might use test that the function function_to_test() does not crash when given the input function_input.
We can write more complicated tests which will do more than simply show us that a function won’t crash. We can use pattern match to throw a ‘badmatch’ error, an example of this would be
This updated example will cause the program to crash and thrown an exception if function_to_test(function_input) does not return []. This is extremely useful if you know the expected output of the function you are testing for the specified input.
We can also go a step further and use Boolean operators by using the assert macro. An example of this is
This will also test that the function will return a certain expected value and assert will either return ok if the test evaluates to true or throw an exception if it does not give the expected return value.
Running EUnit
All you need to do to run the tests you’ve defined on your module which includes the EUnit header is to compile the module, and then run
Which will run all tests defined in your module.
Test Generating Functions
Test generating functions in EUnit return a representation of a set of tests to be executed, this allows you to bypass the need for writing separate test functions with separate names for each test case. EUnit will put all the tests generated by this function into a list and run them one-by-one. Test generated functions have a name ending with …_test_() and adding an underscore in front of the macro which will be used for the test will signal that that macro is a test object. An example of this is
Which when run will test that each of these three inputs to the function to be tested will have the same expected output. Not the underscore in front of the assert macro which signals that this is a test object.
Common Test Basics
The Common Test framework is a tool that supports implementation and automated execution of test cases to any types of target systems. Common Test is the main tool being used in all testing- and verification activities that are part of Erlang/OTP system development and maintenance.
- Common Test is also a very useful tool for white-box testing Erlang code for example (module testing), as the test programs can call exported Erlang functions directly
The Common Test server requires that the test suite defines and exports the following mandatory or optional callback functions:
- all(): Returns a list of all test cases and groups in the suite. (Mandatory)
- suite(): Information function used to return properties for the suite. (Optional)
- groups(): For declaring test case groups. (Optional)
- init_per_suite(Config): Suite level configuration function, executed before the first test case. (Optional)
- end_per_suite(Config): Suite level configuration function, executed after the last test case. (Optional)
- group(GroupName): Information function used to return properties for a test case group. (Optional)
- init_per_group(GroupName, Config): Configuration function for a group, executed before the first test case. (Optional)
- end_per_group(GroupName, Config): Configuration function for a group, executed after the last test case. (Optional)
- init_per_testcase(TestCase, Config): Configuration function for a testcase, executed before each test case. (Optional)
- end_per_testcase(TestCase, Config): Configuration function for a testcase, executed after each test case. (Optional)
For each test case, the Common Test test server expects the following functions:
- Testcasename(): Information function that returns a list of test case properties. (Optional)
- Testcasename(Config): The test case function.
Source: http://erlang.org/documentation/doc-6.3/lib/common_test 1.9/doc/html/basics_chapter.html
Authors: Group 10