fpcunit
fpcunit is a unit testing framework a la DUnit/JUnit/SUnit. This allows you to quickly write a set of test for a (logical) unit of code (not necessarily the same as a Pascal unit, though often it is).
Development methodologies like Test Driven Design use this to make sure you code your expectations/specifications in your unit tests first, then write your main code, then run your tests and improve the code until all tests pass.
Not only does fpcunit allow you to visually inspect test runs, you can also collect the results systematically (using the XML output), and use that to compare versions for e.g. regression errors (i.e. you run your regresssion tests using the unit test output).
Screenshot of the GUI test runner:
The image shows that out of 10 tests run, 6 tests failed. The EAssertionFailure exceptions indicate the test assertions (see below) were not met — i.e. the test failed. The associated messges indicate the result the test expected and the actual result achieved.
Use in FPC/Lazarus
FPCUnit tests are used in the FPC database test framework: Databases#Running_FPC_database_tests
There are also tests for the FPC compiler/core packages, but these presumably predate fpcunit and use a simpler approach.
It’s easiest to use Lazarus to set up a new test project for you. Below are some descriptions of which procedures/methods to use for what purpose.
Setup
This procedure is present in all FPCUnit tests. It sets up the test environment before each test is run — in other words not only before and after the complete test suite is run, but for every test. You can use this to e.g. fill a database with test data.
Teardown
This procedure is present in all FPCUnit tests and is the reverse of Setup. It cleans up the test environment after each test is run. You can use this to e.g. clear test data from a database.
Test decorator: OneTimeSetup and OneTimeTearDown
The Setup and Teardown procedures mentioned above are run once per test. You can also run Setup and Teardown procedures once per instance/execution of your test run.
To do this, use OneTimeSetup and OneTimeTearDown and inherit from the TTestSetup «test decorator» and register it, e.g.:
Tests
You write your own tests as published procedures in the test class (private, protected or public will not work). You can use AssertEquals etc to specify what should be tested, and give a suitable message when the test fails.
If you want to fail a test, you can e.g. use
Note: there must be a better way of doing this.
If the test fails, an EAssertionFailedError will be raised with the message you specify in Assert*. This way, you can add a series of subtests and tell which subtest failed. Note: the test runner will stop at the first assertion failure, so subsequent subtests will not be performed. If you do want to always test everything, split out these subtests in separate test procedures.
Instead of the Assert* procedures, you can also use the DUnit compatible Check* procedures (e.g. CheckEquals) which give more descriptive error messages in the test results: they include expected and actual values.
The order in which the tests are run are the order in which they appear in the test class definition.
Example test
Test hierarchy
In simple cases, you (or Lazarus) would register all your test cases with calls like:
However, you can also create multiple layers to group your test cases if your project gets big:
Custom Test Names
By default the class name of your TTestCase descendant is used as Test Suite Name and the method names are used as Test Case names. You can also assign custom names e.g. if you have a class wich will run different tests depending on some other settings.
The following code will create a test named MyTestName (replacing method name) within MyTestSuiteName (replacing class name).
Automatic modification to the fields
If you add any field to a subclass of TTestCase, you should be aware that those fields will be reseted to their default values before the beginning of a test. I do not consider this to be a bug because tests results should be independent: the result of a test should not depend on the result of any other test. I have reproduced this behaviour in both Windows and Linux Mint XFCE.
If you really need a reliable value for a variable, using class var instead of fields solves the problem.
While performing further testing of this unit, I found that, in the code below, if I replace fx:double; by class var fx:double; the test no longer fails! Declaring one variable a class variable has cleared the problem. This makes me believe that this is a bug.
Usally, bugs are not written to the documentation, but this one has cost us many hours of lost time during unit testing. Furthermore, before reporting any bug, the expected behaviour must be clearly established. This wiki page must describe the expected behaviour. Is the bug is that the fields are assigned to their default values of 0 or is the bug is that when class var is added, they are no longer assigned to 0? According to this reference https://sergworks.wordpress.com/2012/08/31/introduction-to-unit-testing-with-lazarus/ , the bug would be that they are cleared to their default values.
Output
The console test runner can output in XML (either original FPCUnit format, or a more advanced DUnit2-like format if you use the xmltestreport unit), plain text and latex (e.g. usable for PDF export) formats. The GUI test runner outputs to XML if needed (using the same xmltestreport XML format).
Customising output
You can use your own «listener» that listens to the test results and outputs the test data in whatever way you want. Create a T*Listener that implements the ITestListener interface. It’s only 5 required methods to implement.
In your test runner application (e.g. a copy of fpctestconsole), add a listener object; register that test listener with the testing framework (e.g. your console test runner) via the TestResult.AddListener() call, and it will be fed test results as they happen.
Testdbwriter
An example of a custom listener is the database output writer available at https://bitbucket.org/reiniero/testdbwriter. This writer will save all test results to a database, which is optimized for receiving large amounts of test results (handy for using on CI server like Jenkins or for importing/consolidating test results). The mentioned repository contains an example that runs the db test framework test results to (another) database.
To do: adapt this; use the new xml unit
An example of an available extra listener is TXMLResultsWriter in the xmlreporter unit in <fpc>\packages\fcl-fpcunit\src\xmlreporter.pas.
todo: actually, dbtestframework seems to use the old xml output method. An example of an adapted test runner that uses an extra listener can be found in <fpc>\packages\fcl-db\tests\dbtestframework.pas, which contains this code to output to custom listeners (an XML writer and a digest writer that stuffs the output in a .tar archive, handy to process remotely):
Alternatives
-
— a huge improvement over the original DUnit. Originally written for Delphi only, and which is used by the huge test suite of the tiOPF framework.
-
— a fork of DUnit2, and which is tuned specifically for use with the Free Pascal Compiler.
Lazarus
Lazarus has the consoletestrunner and GUI test runner units, which can be installed by installing the FPCUnitTestRunner package. This will help you create and run your unit tests using a GUI (or console, if you want to).
The consoletestrunner is compatible with FPC so you don’t need Lazarus to compile it. The Lazarus version is slightly different to the one in FPC (e.g. use of UTF8 output etc).
The GUI runner is easier to use.
In the GUI runner, if you want to run all tests, currently you first need to click on a test element before the Run all tests button is activated.
GDB bug/feature
Note (September 2012): a bug/undocumented feature in the debugger used by Lazarus/FPC (gdb) means that passing —all as run parameters has no effect. Passing this parameter can be useful when debugging console fpcunit test runners has no effect. Workaround: use -a. See bug [1]
Introduction to unit testing with Lazarus
1. Lazarus 1.0 comes with built-in unit testing framework called FPCUnit. FPCUnit is another Pascal clone of Java JUnit framework, like DUnit framework supplied with Delphi, but different from DUnit in some details.
If you are absolutely new to unit testing (or to Lazarus, like me) create your first unit test project by running the wizard. Select File->New… from IDE menu, choose FPCUnit Test Application and click ‘OK’:

Check two checkboxes and click ‘OK’ in the next dialog: 
The wizard is very primitive, but you need not anything more. You can save the generated unit test project as a template and never run the wizard again.
2. Now time add a unit under test to the project. Most usual unit under test is a class, but it also can be a record with methods, or a pascal unit with flat procedures in interface section. For demonstration purposes I have written TCalc class implementing a simple calculator to be a unit under test:
3. To implement a testing of a unit we create a test case. Our generated unit test project already contains one test case – that is TTestCase1 class. Our unit under test has 3 functions to be tested: the methods TCalc.Clear, TCalc.Add and TCalc.Sub. Edit testcase1.pas unit as follows:
4. Our first unit test project is ready now. Run it and see the result:

5. We created a published method of a test case for every tested function of a unit under test. Unit testing framework includes published methods of test case class into a test runner application. Notice that Setup and TearDown methods of a test case are called every time a published method of a test case is called. When I started to use unit testing I thought that Setup (TearDown) is called when test case class is created (destroyed) – that is not true, they are called ‘per function’.
6. You can add more units under test to a unit test project. If you have several units under test (and correspondent test cases) in a project you can have a separate test register unit. Remove the initialization section from the test case unit, add a second unit testcase2.pas with TTestCase2 test case class (you can make a replica of the first) to the project, and create a new RegTests.pas unit in to register test cases:
Now we have a unit test project with 2 test cases:

7. If your unit test project grows one day you will want to have a hierarchical structure of test cases instead of a flat one. You can create a test hierarchy using a different RegisterTest overload. Create an additional hierarchy levels by updating RegTests.pas unit as follows:

8. Our oversimplified test case class contains all testing code inside the published methods. More realistic published methods are wrappers for other functions which perform actual testing. You may be tempted to add private methods and fields to test case classes; it is OK if your test case class is simple, otherwise you will soon find your test case class cluttered with a mess of methods corresponding to different tests (published methods). My own experience lead me to creating (if needed) a separate helper class for every test. These helper classes inherit from a common base class which provides access to TTestCase functions:
Работа с тестирующей системой, расшифровка сообщений. «Задача A+B» на разных языках
Тестирующая система TestSys расположена по адресу: ts.lokos.net.
Для входа в систему следует использовать логин (обычно — 2 цифры) и пароль выданные преподавателем.
Задача «A+B» на разных языках программирования
Нужно ввести из входного файла два целых числа и вывести их сумму в выходной файл.
Pascal
Delphi
Сообщения тестирующей системы
- Accepted— Все в порядке! Ваша программа принята! Она откомпилировалась без ошибок и прошла все тесты.
- Presentation Error (PE) — неправильный формат вывода, проверяющая программа не смогла прочитать ваш выходной файл или ваша программа вообще не создала выходной файл.
- Wrong Answer (WA)— неправильный ответ на тест.
- Compile Error (CE) — ошибки компиляции программы. Посмотрите что вы отправляете (нажмите view в отправках).
- Runtime Error (RT) — ошибка времени выполнения (выход за границы массива, переполнение переменной, деление на ноль, корень из отрицательного числа, ошибка в имени входного файла).
- Time Limit (TL) — ваша программа выполнялась на каком-то тесте больше времени по условию задачи.
- Memory Limit (ML) — ваша программа использовала больше памяти, чем разрешено по условию задачи.
Компиляторы
- Pascal: Borland Delphi 7.0, Free Pascal 2.6.0;
- C/C++: Visual C++ 2010 Express Edition, GNU C++ 4.6.1 (MinGW), Code::Blocks 10.05;
- C#: Visual C# 2010 Express Edition;
- Java: Sun JDK 7 update 9, Eclipse 4.2.
- Python: Python 3.3.0, Wing IDE 101 4.1.9.
Примеры ошибок в решениях:
Presentation Error (PE)
Неправильное имя выходного файла:
Программа выводит на экран вместо файла:
Wrong Answer (WA)
Точности/разрядности типов данных не хватает:
Compile Error (CE)
Комментарий тестирующей системы:
Runtime Error (RE)
Программа завершилась с ненулевым кодом возврата, либо создала исключительную ситуацию (exception) и не обработала ее.
Online-тестирование
Разработка программы для тестирования студентов в интегрированной среде разработки Lazarus. Создание формы, отображение графического изображения, выхода, ответа, завершения теста. Процесс выбора ответа студентом. Исходный вид программы тестирования.
| Рубрика | Программирование, компьютеры и кибернетика |
| Предмет | Высокоуровневые методы программирования |
| Вид | курсовая работа |
| Язык | русский |
| Прислал(а) | lyucscn |
| Дата добавления | 23.12.2014 |
| Размер файла | 388,4 K |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Подобные документы
Обеспечение универсальности функций тестирования при разработке программы для тестирования студентов. Бесплатное программное обеспечение. Анализ выбора среды программирования. Особенности среды Delphi и СУБД MySQL. Описание алгоритма и блок-схемы.
курсовая работа [1,6 M], добавлен 01.02.2013
Обследование объекта, обоснование необходимости систем компьютерного тестирования. Анализ существующих разработок и обоснование выбора технологии проектирования. Создание системы компьютерного тестирования на основе случайного выбора в среде Visual Basic.
дипломная работа [2,4 M], добавлен 18.08.2013
Способы оценки знаний. WEB-система тестирования студентов. Блок регистрации и авторизации. Категорирование страниц сайта по различным терминам. Создание вопроса с выбором количества правильных вариантов ответа. Система настройки тестов и вопросов в них.
дипломная работа [3,7 M], добавлен 15.04.2012
Создание системы компьютерного тестирования для контроля знаний. Проблемы, возникающие при создании тестовой оболочки в среде Ren`Py. Разработка проектных решений по системе и её частям. Структура тестирования, вопросы и ответы тестирующей системы.
дипломная работа [501,6 K], добавлен 12.09.2016
Проектирование программы в среде Delphi для тестирования знаний студентов по программированию, с выводом оценки по окончанию тестирования. Разработка экранных форм и алгоритма программы. Описание программных модулей. Алгоритм процедуры BitBtn1Click.
курсовая работа [365,0 K], добавлен 18.05.2013
Исторические предпосылки разработки тестирования. Виды электронных тестов и их роль в программировании. Этапы разработки программы для решения задачи быстрой сортировки. Пользовательский интерфейс, отладка, алгоритм программы. Файл теста в формате XML.
курсовая работа [1,5 M], добавлен 27.01.2014
Создание программы на языке Visual C++ с использованием библиотеки MFC для тестирования знаний пользователя в области геометрии. Генерирование тестовых заданий, введение ответа, оценка результата; логическая структура приложения; техническое обеспечение.