Package: baldertest
Balder is a very powerful, universal and flexible python test system that allows you to reuse a once written testcode as
efficiently as possible for different but similar platforms/devices/applications. Balder's goal is
being a platform for combining the single steps of defining, developing and documenting the entire test
process while using test scenarios which can be reused across different projects.You can share your own testcode by creating a new BalderHub project, or you use anexisting BalderHub project, by simply installing and using it. This makes the test development
for your project much faster, since it is often times enough to only provide the user-specific code.Be part of the progress and share your tests with others, your company or the whole world.InstallationYou can install the latest release with pip:python -m pip install baldertestRun BalderAfter you've installed it, you can run Balder inside a Balder environment with the following command:balderYou can also provide a specific path to the balder environment directory by using this console argument:balder --working-dir /path/to/working/dirHow does it work?Balder allows you to reuse previously written test code by dividing it into the components thatare neededfor a
test (Scenario) and the components thatwe have(Setup).Scenarioclasses define a test. Only describe the most important aspectsyou needfor the execution of the
corresponding test (method of the scenario class) insideScenarioclasses. Often it is enough to define abstract
methods in the scenario-level features.In contrast,Setupclasses describe exactly whatyou have. This is where you define all the devices and their
features. Balder will then automatically search for mappings and run your test with them.Define theScenarioclassInsideScenarioorSetupclasses, innerDeviceclasses describe your environment. For example, if you want to test
the process of sending a message between two devices, you can create aScenariolike shown below:importbalderfrom.featuresimportSendMessageFeature,RecvMessageFeatureclassScenarioMessaging(balder.Scenario):classSender(balder.Device):send=SendMessageFeature()@balder.connect(Sender,over_connection=balder.Connection())classReceiver(balder.Device):recv=RecvMessageFeature()You have now defined, that theSenderdevice must be able to send messages (hasSendMessageFeature()), while
theReceiverdevice must be able to receive messages (hasRecvMessageFeature()). Both devices are connected with
each other. For this we use the general connectionbalder.Connection(), which allows every type of connection.You can implement your test, by adding a new method that starts withtest_*():importbalderfrom.featuresimportSendMessageFeature,RecvMessageFeatureclassScenarioMessaging(balder.Scenario):classSender(balder.Device):send=SendMessageFeature()@balder.connect(Sender,over_connection=balder.Connection())classReceiver(balder.Device):recv=RecvMessageFeature()deftest_send_msg(self):MESSAGE_TXT="Hello World"self.Sender.send.send_msg(MESSAGE_TXT)received_msg=self.Receiver.recv.get_last_received_msg()assertreceived_msg==MESSAGE_TXTDefine theSetupclassThe next step is defining aSetupclass, which describes what we have. For aScenarioto match aSetup, all of
your scenario-devices must be able to map to a sub selection of some setup-devices.For example, if you want to verify if your DUT is able to receive messages from your computer (both are connected over
USB), just create aSetupclass with the both devicesComputerandDutand add an implementation (subclasses) of
our previously defined feature classesSendMessageFeatureandRecvMessageFeatureto them:importbalderfrombalderimportconnectionsascnnsfrom.setup_featuresimportSendUsbMessageFeature,RecvUsbMessageFeatureclassSetupOverUsb(balder.Setup):classComputer(balder.Device):# non-abstract subclass of `SendMessageFeature`send=SendUsbMessageFeature()@balder.connect(Computer,over_connection=cnns.UsbConnection())classDut(balder.Device):# non-abstract subclass of `RecvMessageFeature`recv=RecvUsbMessageFeature()With the featuresSendUsbMessageFeatureandRecvUsbMessageFeature, both devices hold an implementation of our
previous scenario-level featuresSendMessageFeatureandRecvMessageFeature. They are the child classes of our
scenario-level features and hold the full implementation for sending/receiving data over USB.As soon as you run Balder, Balder will automatically detect that our scenarioScenarioMessagingcan be mapped to theSetupOverUsb. This will cause Balder to run the testtest_send_msg()with the implemented setup-level version of
the features.The big advantage of Balder is the reusability. If you want to test if the communication also works in the other
direction, just add the features inverted:importbalderfrombalderimportconnectionsascnnsfrom.setup_featuresimportSendUsbMessageFeature,RecvUsbMessageFeatureclassSetupOverUsb(balder.Setup):classComputer(balder.Device):# non-abstract subclass of `SendMessageFeature`send=SendUsbMessageFeature()# non-abstract subclass of `RecvMessageFeature`recv=RecvUsbMessageFeature()@balder.connect(Computer,over_connection=cnns.UsbConnection())classDut(balder.Device):# non-abstract subclass of `SendMessageFeature`send=SendUsbMessageFeature()# non-abstract subclass of `RecvMessageFeature`recv=RecvUsbMessageFeature()Balder will now run the test once with theComputerbeing the sender and once with theDutbeing the Sender, even
though you didn't implement anything new.ScenarioMessaging.SenderScenarioMessaging.SenderVARIATION 1SetupOverUsb.ComputerSetupOverUsb.DutVARIATION 2SetupOverUsb.DutSetupOverUsb.ComputerDo you have another device, that should be tested too? Just add it to your setup:importbalderfrombalderimportconnectionsascnnsfrom.setup_featuresimportSendUsbMessageFeature,RecvUsbMessageFeatureclassSetupOverUsb(balder.Setup):classComputer(balder.Device):# non-abstract subclass of `SendMessageFeature`send=SendUsbMessageFeature()# non-abstract subclass of `RecvMessageFeature`recv=RecvUsbMessageFeature()@balder.connect(Computer,over_connection=cnns.UsbConnection())classDut(balder.Device):# non-abstract subclass of `SendMessageFeature`send=SendUsbMessageFeature()# non-abstract subclass of `RecvMessageFeature`recv=RecvUsbMessageFeature()@balder.connect(Computer,over_connection=cnns.UsbConnection())classAnotherDut(balder.Device):# non-abstract subclass of `RecvMessageFeature`recv=RecvUsbMessageFeature()Now balder will run our scenario once each with the following mappings:ScenarioMessaging.SenderScenarioMessaging.SenderVARIATION 1SetupOverUsb.ComputerSetupOverUsb.DutVARIATION 2SetupOverUsb.DutSetupOverUsb.ComputerVARIATION 3SetupOverUsb.ComputerSetupOverUsb.AnotherDutIf you want to test aDutdevice that does not use USB for communication, you can also add other feature
implementations ofSendMessageFeatureandRecvMessageFeaturein your setup devices. For this we just add a new
setup:importbalderfrombalderimportconnectionsascnnsfrom.setup_featuresimportSendUsbMessageFeature,RecvUsbMessageFeature,SendBluetoothMessageFeature,RecvBluetoothMessageFeatureclassSetupOverUsb(balder.Setup):...classSetupOverBluetooth(balder.Setup):classComputer(balder.Device):# non-abstract subclass of `SendMessageFeature`send=SendBluetoothMessageFeature()@balder.connect(Computer,over_connection=cnns.BluetoothConnection)classDut(balder.Device):# non-abstract subclass of `RecvMessageFeature`recv=RecvBluetoothMessageFeature()If you now execute Balder, it will run the scenario with all possible device constellations of theSetupOverUsband
theSetupOverBluetooth.ScenarioMessaging.SenderScenarioMessaging.SenderVARIATION 1SetupOverUsb.ComputerSetupOverUsb.DutVARIATION 2SetupOverUsb.DutSetupOverUsb.ComputerVARIATION 3SetupOverUsb.ComputerSetupOverUsb.AnotherDutVARIATION 4SetupOverBluetooth.ComputerSetupOverBluetooth.DutNOTE:You could also add all of these devices in a shared setup and use one common feature for both protocols, but for this you would need to use VDevices. You can read more about this inthe documentation section about VDevicesExample: Use an installable BalderHub packageWith Balder you can create custom test environments or install open source available test packages, so calledBalderHub packages. If you want to test a SNMP client device for example, you can use thepackage balderhub-snmpagent. Just install it with:$ pip install balderhub-snmpagentYou only need to provide two things: The configuration of your DUT as subclass ofSnmpSystemConfigand your
environment (theSetupclass):# file `features.py`frombalderhub.snmpagent.libimportfeaturesclassMySnmpSystemConfig(features.SnmpSystemConfig):host="192.168.178.28"sys_descr="my fancy sysDescr"sys_object_id="1.3.6.1.4.1.1234.2.3.9.1"read_community="public"write_community="public"# file `setup_example.py`importbalderfrombalderhub.snmpagent.lib.connectionsimportSnmpConnectionfrombalderhub.snmpagent.lib.featuresimportHasSnmpSystemGroupFeaturefrombalderhub.snmpagent.lib.setup_featuresimportSendSnmpGetRequestPysnmpFeature,SendSnmpSetRequestPysnmpFeaturefrom.importfeaturesassetup_featuresclassSetupPrinter(balder.Setup):classPrinter(balder.Device):_snmp_sys=HasSnmpSystemGroupFeature()config=setup_features.SnmpSystemConfig()@balder.connect(Printer,over_connection=SnmpConnection())classHostPc(balder.Device):get_request_snmp=SendSnmpGetRequestPysnmpFeature()set_request_snmp=SendSnmpSetRequestPysnmpFeature()Call Balder in your project:$ balderAnd all existing and matching tests inbalderhub-snmpagentwill
then be executed for you:+----------------------------------------------------------------------------------------------------------------------+
| BALDER Testsystem                                                                                                    |
|  python version 3.10.6 (main, Mar 10 2023, 10:55:28) [GCC 11.3.0] | balder version 0.1.0b6                           |
+----------------------------------------------------------------------------------------------------------------------+
Collect 1 Setups and 3 Scenarios
  resolve them to 3 mapping candidates

================================================== START TESTSESSION ===================================================
SETUP SetupPrinter
  SCENARIO ScenarioMibSysDescr
    VARIATION ScenarioMibSysDescr.SnmpAgent:SetupPrinter.Printer | ScenarioMibSysDescr.SnmpManager:SetupPrinter.HostPc
      TEST ScenarioMibSysDescr.test_get_sys_descr [.]
      TEST ScenarioMibSysDescr.test_get_sys_descr_ascii_check [.]
      TEST ScenarioMibSysDescr.test_set_sys_descr [.]
  SCENARIO ScenarioMibSysObjectId
    VARIATION ScenarioMibSysObjectId.SnmpAgent:SetupPrinter.Printer | ScenarioMibSysObjectId.SnmpManager:SetupPrinter.HostPc
      TEST ScenarioMibSysObjectId.test_get_sys_object_id [.]
      TEST ScenarioMibSysObjectId.test_set_sys_object_id [.]
  SCENARIO ScenarioMibSysUpTime
    VARIATION ScenarioMibSysUpTime.SnmpAgent:SetupPrinter.Printer | ScenarioMibSysUpTime.SnmpManager:SetupPrinter.HostPc
      TEST ScenarioMibSysUpTime.test_get_sys_up_time [.]
      TEST ScenarioMibSysUpTime.test_get_sys_up_time_changed_check [.]
      TEST ScenarioMibSysUpTime.test_set_sys_up_time [.]
================================================== FINISH TESTSESSION ==================================================
TOTAL NOT_RUN: 0 | TOTAL FAILURE: 0 | TOTAL ERROR: 0 | TOTAL SUCCESS: 8 | TOTAL SKIP: 0 | TOTAL COVERED_BY: 0Contribution guidelinesAny help is appreciated. If you want to contribute to balder, take a look into thecontribution guidelines.Balder is still in its early steps. Unfortunately, this also means that we don't have a broad variety ofBalderHub projectsat the moment.Are you an expert in your field? Do you enjoy the concept of balder? How about you create your own
BalderHub project? Take a look into ourBalder GitHub Groupand feel free to share
your ideas. You can contribute to an existing project or create your own. If you are not sure, a project for your idea
already exists or if you want to discuss your ideas with others, feel free tocreate an issue in the BalderHub main entry projectorstart a new discussion.LicenseBalder is free and Open-SourceCopyright (c) 2022 Max Stahlschmidt and othersDistributed under the terms of the MIT license