Porównanie narzędzi do tworzenia testów automatycznych

Aplikacje internetowe

Selenium – free
framework służący do automatyzacji testów aplikacji webowych pod większość przeglądarek. Testy automatyczne w Selenium można pisać z wykorzystaniem m.in. Python, Java, PHP. Chcąc korzystać w pełni z możliwości automatyzowania, należy wybrać Selenium WebDriver, jednak, aby rozpocząć w nim pracę, należy znać podstawy programowania w języku programowania wspieranym dla Selenium WebDriver. Dla osób, które nie mają doświadczenia, można wykorzystać Selenium IDE, które jest wtyczką pod przeglądarkę Mozilla Firefox i działa na zasadzie “nagraj i odwtórz”. Testowanie za pomocą narzędzia Selenium IDE można wykorzystać przy powtarzalnej weryfikacji formularzy. Istnieją dwa oddzielne framework’i (Selendroid i Appium) które są przystosowane do testowania aplikacji mobilnych. Selendroid i Appium działają na bazie Selenium.

Plusy:
– możliwość (po wytworzeniu scenariusza testowego) odtwarzania kroków w sposób powtarzalny
– przy dobrze dobranych scenariuszach i np. uruchamianiu i utrzymywaniu testów automatycznych aplikacji, większa kontrola nad potencjalnym defektami w systemie
– Selenium IDE – nagraj i odtwórz
– masa poradników

Minusy:
– utrzymywanie testów z każdą zmianą aplikacji kosztuje

 

Sahi – freemium
narzędzie służące do automatyzacji aplikacji webowych. Udostępnione są dwie wersje narzędzia – jedna darmowa na zasadach Open-Source, druga jest wersją komercyjną. Wersja Open-Source posiada podstawowe narzędzia, które w zupełności wystarczą, aby rozpocząć automatyzację testów z wykorzystaniem tego narzędzia. W przeciwieństwie do Selenium, Sahi posiada możliwość nagrywania testów na dowolnej wspieranej przeglądarce (Internet Explorer, Firefox, Chrome, Safari, Opera, Edge).

Plusy:
– podstawowe narzędzia wystarczające do testów automatycznych
– nagrywanie testów na każdej możliwej przeglądarce

Minusy:
– brak możliwości testowania aplikacji mobilnych

 

Tellurium – freemium
narzędzie służące do automatyzacji aplikacji webowych, wspierające testy na wielu przeglądarkach (Firefox, Chrome, Internet Explorer). Narzędzie to od dłuższego czasu nie jest jednak rozwijane. Aplikacja jest dostępna za darmo przy uruchomieniu jednego testu. Testy automatyczne w tym oprogramowaniu pisze się za pomocą słów kluczowych w języku angielskim. Chcąc używać tego narzędzia, nie jest wymagana znajomość żadnego języka programowania.

Plusy:
– proste testy przy pomocy słów kluczowych

Minusy:
– tylko jeden test w tym samym czasie
– narzędzie nie jest juz rozwijane (!)

 

Katalon Studio – free
pełna platforma z przeznaczeniem do testów automatycznych aplikacji webowych oraz mobilnych. Tworzenie testów odbywa się za pomocą wbudowanego rekordera zdarzeń lub za pomocą języka skryptowego. Narzędzie jest rozwijane, często uaktualniane i ulepszane. Zaskakuje prostotą użycia, dobrze przygotowaną dokumentacją i przykładami użycia. Katalon powzala na zbudowanie i uruchomienie projektu z konsoli, ale nie pozwala sterować wykonywaniem testów i danymi z trybu terminala – to uniemożliwia uruchomienie testów inaczej, niż tylko z wewnątrz IDE.

Plusy:
– testy WEB
– testy Androida i iOS
– nagraj i odtwórz
– tworzenie testów przy pomocy języka skryptowego

Minusy:
– wyeksportowanie testów i uruchomienie ich z serwera jest arcytrudne
– utrzymywanie testów z każdą zmianą aplikacji kosztuje

 

TestComplete – free
łatwe w obsłudze narzędzie do przeprowadzania testów automatycznych. Narzędzie wspiera testowanie aplikacji flash, flex, AIR, HTML5, Silverlight.

Plusy:
– testy Windows Desktop
– testy WEB
– testy aplikacji mobilnych

Minusy:
– tylko Windows

 

Testy aplikacji desktopowych

Sikulix – free
narzędzie, które powstało na podstawie projektu Sikuli, służącego do automatyzacji elementów z różnych aplikacji desktopowych. Aplikacja działa zarówno pod kontrolą systemu Windows, jak i Mac. Posiada również wsparcie dla systemów Linux/Unix, lecz nie zawsze jest się w stanie zautomatyzować wyświetlające się elementy. Sikulix wspiera całą rzeszę języków skryptowych, w których to możemy oprogramować testy, jak Python, JRuby czy JavaScript. Trzeba jednak zaznaczyć, że jest to aplikacja z dużym ograniczeniem i automatyzowanie w niej złożonych projektów będzie bardzo czasochłonne, a nawet niemożliwe ze względu na identyfikację elementów.

Plusy:
– dobre narzędzie do nagrywania macro
– działa na Windows i MacOS
– różne języki skryptowe

Minusy:
– utrzymywanie testów z każdą zmianą aplikacji kosztuje
– zmiana nazwy pliku w aplikacji jest w stanie zawiesić test
– Java JRE 6 x86 jest wymagana

 

AutoIT – free
darmowe narzędzie służące do automatyzacji elementów wyświetlających się na GUI. Automatyzacja polega na symulacji klawiszy, ruchów myszki. Aplikacja przeznaczona jest na systemy operacyjne Windows. Testy pisze się w języku skryptowym podobnym do BASIC’a, więc nawet niedoświadczona osoba jest w stanie dość szybko rozpocząć pracę z tym narzędziem. Bardzo dobre narzędzie do automatyzowania czynności, można w łatwy i szybki sposób stworzyć skrypty, które przyspieszą i ułatwią naszą pracę. Paleta funkcjonalności sprawia, że narzędzie jest bardzo funkcjonalne.

Plusy:
– prosty język skryptowy
– prostota obsługi
– sporo możliwości

Minusy:
– tylko Windows

 

LordUI – freemium
Bardzo dobre narzędzie chociaż w wersji darmowej posiada wiele ograniczeń, wsparcie twórcy oraz obszerny wachlarz możliwości sprawia że narzędzie może być wykorzystywane w dużych i profesjonalnych projektach. Korzystanie z narzędzia nie przysparza większych problemów, a dostępne przykłady i łatwość tworzenia skryptów sprawiają, że już po paru minutach mamy w pełni działający skrypt.

Plusy:
– prostota obsługi
– możliwość implementacji własnego kodu w Javie

Minusy:
– ograniczenia wersji darmowej
– tylko Windows

 

AutoHotKey – free
Narzędzia można używać podczas przeprowadzania testów oraz podczas standardowej pracy w systemie poprzez automatyzowanie często wykonywanych czynności. Czynnościom tym przypisujemy odpowiedni skrót klawiszowy.

Plusy:
– prostota obsługi
– duża ilość poradników

Minusy:
– tylko Windows

 

Rational Functional Tester – licencja
jeden z najbardziej rozbudowanych, ale jednocześnie najdroższym narzędziem przeznaczonym do automatyzacji GUI systemu operacyjnego. Za pomocą tej platformy można zautomatyzować systemy, które napisane zostały w technologiach Java, SAP, Windows Form itp. Skrypty tworzy się w jednym z dwóch języków programowania – Java lub Visual Basic.NET.

Plusy:
– rozbudowane narzędzie

Minusy:
– cena
– twórcy nie nadganają technologii
– brak wsparcia dla MacOS

 

Testy wydajnościowe

WebLoad – freemium
narzędzie służące do przeprowadzania testów wydajnościowych aplikacji webowych, które korzystają z takich technologii i protokołów, jak HTML5, HTTPS, AJAX, JSON, Adober Air itp. Posiada możliwość integracji z tak popularnymi narzędziami jak Selenium. JENKINS, APPium, Dynatrace. Narzędzie to ma wbudowane rekordy, za pomocą których można tworzyć nagrania własnych akcji i ich późniejszego symulowania. WebLoad posiada w swojej ofercie darmową wersję aplikacji, pozwalającą na symulowanie zachowań maksymalnie 50 wirtualnych użytkowników.

Plusy:
– integracja z Selenium
– nagraj i odtwórz

Minusy:
– darmowy do 50 użytkowników

 

ApicaLoadTest – free
pozwala na przeprowadzenie testów obciążeniowych z wielu centrów testowych, symulując pracę nawet 2 milionów jednoczesnych użytkowników. Za pomocą tego narzędzia jesteśmy w stanie przeprowadzić testy zarówno aplikacji webowych, jak i aplikacji z przeznaczeniem na urządzenia mobilne, takie jak iOS czy Android. Dodatkowo w sytuacji, gdy nie mamy własnych zasobów do przeprowadzenia testów, możemy wszystko zlecić firmie Apica. ApicaLoadTest integruje się z popularnymi narzędziami ciągłej integracji, na przykład Bamboo czy JENKINS.

Plusy:
– duża baza symulowanych użytkowników
– testy mobilek

 

JMeter – free
najpopularniejsze narzędzie typu open source, które służy do przeprowadzania testów wydajnościowych. Uznane jest w świecie testerskim. Aplikacja pozwala na symulowanie zachowań użytkowników z jednego komputera lub pracy w klastrze. JMeter pozwala na przeprowadzanie testów wydajnościowych różnych obiektów systemów – od serwisów internetowych napisanych w PHP, Java, ASP.NET po serwery FTP. Narzędzie to działa zarówno na systemach linuksowych oraz na Windowsie. JMeter posiada wbudowany rekorder, co pozwala nagrywać akcje użytkownika, a następnie symulować je dla wielu użytkowników.

Plusy:
– masa poradników
– rozbudowane narzędzie
– testy serwerów FTP
– nagraj i odtwórz
– działa na MacOS (Homebrew)

 

CloudTest – freemium
może być wykorzystywany do testów wydajnościowych aplikacji internetowych, aplikacji mobilnych, interfejsów API i wielu innych. Chcąc sprawdzić oprogramowanie, można zainstalować wersją próbną, która umożliwia zasymulowanie pracy maksymalnie 100 równoczesnych użytkowników. Narzędzie to pozwala w łatwy sposób importować skrypty z JMetera i wykorzystywać je w ramach testów. Symulacja jest przeprowadzana z wielu lokalizacji na świecie jednocześnie, a wyniki testów możemy śledzić w czasie rzeczywistym.

Plusy:
– testy aplikacji mobilnych
– integracja z JMeter
– symulacja z różnych serwerów jednocześnie

Minusy:
– darmowa wersja do 100 użytkowników równoczeście

 

LoadStorm – freemium
narzędzie pozwalające na przeprowadzenie testów wydajnościowych, które jest udostępnione w chmurze. Wszystkie operacje i testy wykonuje się zdalnie za pomocą aplikacji internetowej. LoadStorm posiada możliwość symulacji użytkowników z różnych lokalizacji na świecie.

Plusy:
– symulacja z różnych serwerów jednocześnie
– działa w chmurze

 

HP LoadRunner – freemium
narzędzie to integrujące się z innymi narzędziami deweloperskimi, takimi jak jUNIT, Jenkins czy Selenium. Wspiera również przeprowadzanie testów wydajnościowych strumieni audio i wideo. Testy możemy tworzyć za pomocą wbudowanego rekordera lub za pomocą języka skryptowego.

Plusy:
– integracja z Selenium
– testy streamów
– nagraj i odtwórz

Flutter – mobile cross platform technology overview.

Some time ago Google introduced a Flutter – technology for creating cross platform mobile applications. In theory app written in flutter should work as fast as native app and it’s development should be fast and easy. In this article I’ll look closer into it and compare different aspects of development a flutter app.

Programming language

Dart – it’s the language created and used by Google in Flutter. But why Dart? Most of all it’s easy to learn and it’s syntax is very similar to most of the popular object oriented languages – including swift and kotlin. Most of the common IDE’s such as Intelij Idea and Android Studio have support for dart. Beside Flutter works in the way that it needs to create and destroy a lot of short-lived objects very fast and Dart is suitable for this which influences performance of the apps written in Flutter.

User interface

What makes Flutter special when it comes to UI design? First of all it’s approach for creating it. Opposite to other mobile technologies it does not use XML/JSX/other templating language, does not offer any visual editor and there are no separate layout files such as xml/xib/storyboard. Instead it keeps everything together and all is written in Dart. You can think that creating layouts is much faster and easier using a visual tool and keeping UI code along with logic can be messy and make code more complicated and less readable. I also used to think this way, but when I tried it and wrote my first Flutter app I’ve changed my mind right away. I was shocked how easy and clear it is. Let’s consider a sample app code with comments removed.

import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: new Center(
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            new Text(
              'You have pushed the button this many times:',
            ),
            new Text(
              '$_counter',
              style: Theme.of(context).textTheme.display1,
            ),
          ],
        ),
      ),
      floatingActionButton: new FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: new Icon(Icons.add),
      ),
    );
  }
}

That’s it! It’s all code required to run the app, and it even count button clicks! Everything is in one place and it’s quite readable. When you writing native iOS application you have to open storyboard, add view controller, put some components in it, add constraints, connect it with a class, add outlets and then switch between storyboard and code. It’s hard to remember everything. Did I set table delegate in code or in storyboard? Did I set the delegate at all? I have to switch and check. Flutter doesn’t have this and instead jumping across files you can focus on your job. Thanks to that creating UI is even faster than using a visual editor.

You’re missing visual representation of UI? No problem! Flutter offers a hot reload feature that allows changes you made in code to be reflected in app without loosing it’s state. This works fine even for big and complicated apps and thanks to this you can check your work instantly and no need to recompile, restart the app and navigate to a screen you’re working on.

In Flutter everything is a widget: a screen, UI component, even stylistic element or behaviour. Because of that building UI or defining it’s behaviour is based on wrapping widgets into other widgets to achieve desired goal, which makes laying out views easier. Layout elements such as padding is also a widget, so other widgets don’t have to have a padding property. If you want a padding, then you wrap widget in a padding widget and that’s it. This makes the API lighter, easier and more intuitive. It also gives a hudge possibilities of customizing and creating you own widgets from smaller widgets. The downside of that solution can be large code nesting when dealing with more complex views, but it can be prevented by dividing widgets into smaller widgets or splitting the code to methods.

Another pain for developers when writing native applications is lifecycle management. Due to his reactive nature Flutter doesn’t have this. You don’t need to worry about managing asynchronous data loading and local state management and coordinate it with UI. If asynchronous operation finishes and you want to change something in the widget – you just change it’s state and a widget will be repainted.

Performance

Flutter doesn’t use a Web Views or OEM widgets. Instead it uses his own rendering engine to draw widgets which results in better performance. It has very thin layer of C/C++ code and most of it’s systems are written in Dart. When building apps the C/C++ engine code is compiled with Android NDK or with LLVM for iOS. The Dart code is compiled using AOT (ahead of time) compiler into a native ARM library. That library is added to the “runner” project and it is builded just like a native application into .apk or .ipa. When launched, the app uses Flutter library to handle events, rendering etc. You can see it on the High-level overview diagram below.

(source: https://docs.google.com/presentation/d/1cw7A4HbvM_Abv320rVgPVGiUP2msVs7tfGbkgdrTy0I/edit#slide=id.gbb3c3233b_0_162)

According to flutter developers:

“Flutter’s widgets incorporate all critical platform differences such as scrolling, navigation, icons and fonts to provide full native performance on both iOS and Android.”

Flutter apps are compiled to native code, so performance is competitive with native apps. It aims to offer 60 fps, or 120 fps on 120 Hz devices. Using widgets that are fast makes apps working fast and smooth even with complicated effects and animations. Instead having a large number of layout constraints, each widget have it’s own simple layout model and Flutter use caching to avoid repeating layout the same widget couple of times. Reactive nature makes it render quickly and work fast, but in apps that changes in widgets are frequent and there is a lot of quick reloads it can be slower and more resource consuming than in native app.

Summing up

Flutter is still in early version. There are some bugs and shortcomings, but it’s getting better and it develops very fast. UI designing is fast and easy, you can create a beautiful widgets and animations pleasing to the eye which attract your customers. Code is clean, readable and writing mobile apps nice and effective. For me it’s one of the best mobile cross-platform frameworks and a good alternative for native technologies. It can be compiled both for android and iOS, so instead writing two apps you can write one and reduce needed time by half, without being worse than native applications in the matter of performance.

Resources: https://flutter.io/

Building a simple SRI list-details application

Sri (Scalajs React interface) is a library based on react-native, that allows to use scalajs programming language to build native Android and iOS apps. In this article I’ll show You how to build a simple app using sri. This app will be a simple stack-navigation app containing list and details views. Let’s get started.

First thing you need to do is to set up your environment. Those are the things you need to get started(You need homebrew to run following commands: https://brew.sh/, If you already have those installed you can skip this part):

brew install node
brew install watchman
brew install sbt
npm install -g react-native-cli

Next you need to create a new project. To do that follow instructions on: https://github.com/scalajs-react-interface/sri/blob/master/docs/GettingStarted.md#stack-navigation.
After you have created your project and have packager running use sbt ~ios:devand sbt ~android:devcommands to build it for both platforms. Those commands also run compiler that listen for any scala source files changes and compile it. When you’re developing You should keep one running (depending on platform you’re running) so changes you’ve made in the code are automatically builded and reflected in the app.

Using react-native run-iosor react-native run-androidyou can run your app to see if it’s working. It requires to have Xcode / Android Studio with AVD installed (for instructions on how to set up SDK and simulators see: https://facebook.github.io/react-native/docs/getting-started.html). It may be required to manually run simulator.

If you’re getting ":CFBundleIdentifier", Does Not Existerror while running on iOS, it may help to run react-native upgrade in the root directory of the project.
If you’re getting Application has not been registerederror, open src/main/scala/…/MobileApp.scala file and in line AppRegistry.registerComponent("main", () => component)make sure that in the place of “main” is the name of Your app.

At the beginning create a new scala file called ListScreen. We’ll use it to display a list of people. Class ListScreen must inherit from NavigationScreenComponentNoPS class so it can be display as a view. It should look like:

class ListScreen extends NavigationScreenComponentNoPS {
  def render() = {
    		View(style = GlobalStyles.wholeContainer)()
  	}	
}

Right now main view in our app is AboutScreen. It’s determined in package.scala file. To change default view modify line:

registerStackScreen[AboutScreen](navigationOptions = NavigationStackScreenOptions(title = "About"))

to:

registerStackScreen[ListScreen](navigationOptions = NavigationStackScreenOptions(title = "List"))

From now on when we run our app, it will display ListScreen view which is currently empty. To display a list, first thing we need to do is to create a model class describing a Person object. It should look like this:

trait Person extends js.Object {
 	val firstName: String
  val lastName: String
  	val description: String
  	val age: Int
  	val key: Int
}

Each object on the list need to have a key field unique to each object. Create an array with a example data which will be used to populate our list.

val persons = js.Array(
    	new Person {
      		override val firstName: String = "John"
      		override val lastName: String = "Smith"
      		override val description: String = "Lorem ipsum dolor sit amet, ius ad pertinax oportere accommodare, an vix civibus corrumpit referrentur."
      		override val age: Int = 30
      		override val key: Int = 0
    	}.asInstanceOf[Person],
    	new Person {
      		override val firstName: String = "Steve"
      		override val lastName: String = "Cooper"
      		override val description: String = "Te nam case ludus inciderint, te mea facilisi adipiscing."
      		override val age: Int = 28
      		override val key: Int = 1
    	}.asInstanceOf[Person],
    	new Person {
      		override val firstName: String = "Katie"
      		override val lastName: String = "Dixon"
      		override val description: String = "Sea id integre luptatum. In tota sale consequuntur nec. Erat ocurreret mei ei."
      		override val age: Int = 24
      		override val key: Int = 2
    	}.asInstanceOf[Person]
)

Define styles

object styles extends InlineStyleSheetUniversal {
  	import dsl._

  	val headerFooter = style(
    		height := 30,
    		width := 100,
    		alignSelf := "center",
    		alignItems := "center",
    		justifyContent := "center"
  	)
  	val separator = style(
    		height := StyleSheet.hairlineWidth,
    		backgroundColor := "gray"
  	)
  	val item = style(
    		flex := 1
  	)
  	val itemRow = style(
    		flexDirection := "row",
    		padding := 10,
    		backgroundColor := "#F6F6F6"
  	)
  	val text = style(
    		flex := 1
  	)
}

Create PersonComponent which will represent a single row of the list

class PersonComponent extends ComponentP[PersonComponent.Props] {
  	def render() = {
    		TouchableHighlight(
      			onPress = () => props.onPress(props.item.key),
      			style = styles.item)(
      			View(style = styles.itemRow)(
        			Text(style = styles.text,
          				numberOfLines = 2 )(
          				s"${props.item.firstName} ${props.item.lastName}\n${props.item.age}"
        			)
      			)
    		)
  	}
}

object PersonComponent {
  	case class Props(item: Person,
    onPress: Int => Unit)
  	def apply(props: Props) = CreateElement[PersonComponent](props)
}

Define separator, header and footer

val SeparatorComponent = View(style = styles.separator)(null)
  
val HeaderComponent = ViewC(
  View(style = styles.headerFooter)(
   		TextC("LIST HEADER")
    	),
    	SeparatorComponent
)

val FooterComponent = ViewC(
  SeparatorComponent,
    	View(style = styles.headerFooter)(
      		TextC("LIST FOOTER")
    	)
)

Define functions for rendering and onPress handling

private def renderItem(info: ListItem[Person]) = PersonComponent(
    	PersonComponent.Props(item = info.item, onPress = pressItem)
)

private def pressItem(index: Int) = {
}

Add a list to render method:

def render() = {
    	FlatList(
      		data = persons,
      		ListHeaderComponent = () => HeaderComponent,
      		ListFooterComponent = () => FooterComponent,
      		ItemSeparatorComponent = () => SeparatorComponent,
      		debug = false,
      		horizontal = false,
      		disableVirtualization = false,
      		renderItem = renderItem _
    	)
}

Now save changes, and if you’ve done all steps correctly, the app should display a list of people, but when you tap on someone, nothing happens. To add details, let’s create a new file named DetailsScreen. DetailsScreen class just like ListScreen class must inherit from NavigationScreenComponent and contains render method, but this time, we want to pass a Person which details should be displayed. You must declare, that during creation of a new instance of DetailsScreen.

class DetailsScreen extends NavigationScreenComponentP[Person] {
  	def render() = {
    		View()(
      			TextC(s"${params.get.firstName} ${params.get.lastName}\n${params.get.age}\n${params.get.description}")
    		)
  	}
}

Each view must be registered. Add below line to package.scala file, just after registration of ListScreen

registerStackScreen[DetailsScreen](navigationOptions = NavigationStackScreenOptions(title = "Details"))

To open details by clicking on a person on the list modify pressItem method like so

private def pressItem(index: Int) = {
  navigation.navigate[DetailsScreen](persons(index))   
}

Now your app displays a list, and when you tap on a person it shows details of that person.