Testo-lang: simple automation for complex tests

Automating End-to-End tests has never been easier

  • The software doesn’t have (or just can’t have, for security reasons) an API you can hook up with.
  • The software is legacy and was developed back in times when no one bothered with the tests’ automation.
  • The software’s testing involves some third-party software (antivirus, for instance).
  • The software must be tested under numerous target operating systems.
  • You can’t test the software without a complex heterogeneous test bench with intermediate network nodes.
mouse_click_on_button_with_text "Save"
type_on_the_keyboard "Hello world"
wait_for_the_text_to_appear "Complete"
mouse click "Save"
type "Hello world"
wait "Complete"
  1. Click the “Save” text on the screen.
  2. Type the “Hello world” text on the keyboard.
  3. Wait for the “Complete” text to appear on the screen.

OK, I’m listening

machine my_super_vm {
ram: 2Gb
cpus: 2
iso: "ubuntu_server.iso"
disk main: {
size: 5Gb
}
}
test my_super_test {
my_super_vm {
start
wait "Language"
press Enter
wait "Install Ubuntu Server"
press Enter
wait "Choose the language"
press Enter
# And so on
...
}
}
machine my_super_vm {
ram: 2Gb
cpus: 2
disk main: {
source: "prepared_vm.qcow2"
}
}
machine my_win_vm {
ram: 2Gb
cpus: 2
disk main: {
source: "my_windows_10.qcow2"
}
}
test my_installer_test {
my_win_vm {
# Power on the virtual machine
start
# Wait for the Desktop to show up
wait "Recycle Bin"
mouse dclick "my_super_installer"
wait "Welcome"
mouse click "Next"
wait "Destination folder"
mouse click "Next"
wait "Complete" timeout 10m
mouse click "Finish"
}
}

What is that “wait” of yours and how does it work?

  1. Interaction with virtual machines (mouse move/click, type, press, start/stop, plug flash and many more).
  2. Analyzing the screen contents (wait).
  1. It is assumed that the OCR system doesn’t know anything about the actual screen contents. It doesn’t know what text should or shouldn’t be displayed at the moment.
  2. The system’s objective is to collect as much information from the screenshot as possible.
  1. You know for sure what text should be displayed on the screen at the moment.
  2. Your objective is much simpler: just tell if the expected text is displayed on the screen or not. If the text is on the screen, then collect the information about its placement (extract its coordinates, basically).

Wait actions are not everything you might need

Developing long tests with just the wait + click combination may be quite tedious, especially when there’s no test recorder available. Visual checks should be considered as the last resort, when every other way to do a check is not sufficient. Normally you’d rather prefer performing checks with something more like a bash-script.

test my_super_test  {
my_super_vm {
exec bash "echo Hello world from bash"
exec python """
print("Hello from python")
"""
}
}
test copy_demo {
my_super_vm {
copyto "/file/on/host" "/file/on/guest"
copyfrom "/file/on/guest" "/file/on/host"
}
}

But why bother with the whole new language?

  1. We’d wanted for Testo to be as easy as possible, so that even non-programmers could use it.
  2. We’d wanted to get rid of all the unnecessary overcomplicated stuff that you can usually see in a general-purpose programming language. We’ve kept only the tests-related things.
  3. Some concepts we’ve implemented just can’t be easily put into a python library!
test run_installator {
my_super_vm {
copyto "/path/on/host.msi" "C:\\setup.msi"
mouse dclick "setup"
...
}
}
  1. The test itself hasn’t changed.
  2. The installer’s build hasn’t changed.

Wow, cool. What else can Testo do?

# Network to link up virtual machines
network net1 {
mode: "internal"
}
# Network for the Internet access
network internet {
mode: "nat"
}
machine my_super_client {
...
nic server_side: {
attached_to: "net1"
}
nic internet: {
attached_to: "internet"
}
}
machine my_super_server {
...
nic client_side: {
attached_to: "net1"
}
}
flash my_super_flash {
fs: ntfs
size: 2048Mb
# The folder on the Host to copy
folder: "/path/on/host"
}
  1. OS installation.
  2. Testo guest additions installation.
  3. Copying the application that you want to test inside the virtual machine and its installation.
  4. Feature 1 testing.
  5. Feature 2 testing.
test install_os {
...
}
test install_guest_additions: install_os {
...
}
test install_app: install_guest_additions {
...
}
test test_feature_1: install_app {
...
}
test test_feature_2: install_app {
...
}

A simple, yet quite real example

It can take several articles to describe all the things that Testo can do. So, I don’t want to overcomplicate this paper and I’d rather demonstrate a basic, real example of testing a simple custom standalone app MySuperApp.

machine my_vm {
cpus: 2
ram: 4Gb
disk main: {
source: "${QEMU_DISK_DIR}/win10.qcow2"
}
}
flash my_super_flash {
fs: "ntfs"
size: 16Mb
folder: "./dist"
}
test launch_my_simple_app {
my_vm {
...
}
}
start
wait "Recycle Bin" timeout 10m
plug flash my_super_flash
mouse click "USB Drive (E:)"
mouse click "Open folder to view files"
mouse dclick "MySuperApp"
wait "Hello world"
test launch_my_simple_app {
my_vm {
start
wait "Recycle Bin" timeout 10m
plug flash my_super_flash
mouse click "USB Drive (E:)"
mouse click "Open folder to view files"
mouse dclick "MySuperApp"
wait "hello world"
unplug flash my_super_flash
}
}
sudo testo run my_script.testo --param QEMU_DISK_DIR /var/lib/libvirt/qemu/images

Conclusions

End-to-End tests are never easy, but always pay back. We hope, that with Testo you can conveniently test your applications in the most various surroundings. Now you can make sure that your apps work just as well on the customer’s side, as on yours.

--

--

Head developer of Testo Framework

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store