let’s dev GmbH & Co. KG - Die Marke für wegweisende Individualsoftware

Blog

Top!

let’s dev | Scroll to top
let’s dev | Scroll to next content item

Hello

let’s dev | Scroll to previous content item
let’s dev Blog | Einführung in User Interface (UI) Tests mit Espresso
by Raphael
07. June 2018

Einführung in User Interface (UI) Tests mit Espresso

Das Sicherstellen von Softwarequalität mithilfe von Tests ist ein wichtiges Thema in der Softwareentwicklung. Hierdurch können frühzeitig Fehler festgestellt und behoben werden. Auch Fehler, die im weiteren Verlauf der Programmierung entstehen, werden so ersichtlich.

In Android unterscheidet man grundlegend zwischen zwei Arten von Tests: Den Unit Tests und den Instrumentation Tests. Im nachfolgenden Beitrag sollen User Interface Tests (UI-Tests), eine Art der Instrumentation Tests, näher betrachtet werden. Hervorzuheben ist an dieser Stelle jedoch, dass nur durch den Einsatz aller Testarten die Qualitätssicherung des Codes optimal gewährleistet ist.

UI-Tests

In der klassischen Programmierung wird die Codebase hauptsächlich mit Unit- und Integration-Tests abgedeckt. Das sollte man auch bei der Programmierung für Android so handhaben. In diesem Beitrag wird jedoch das Sicherstellen eines fehlerfreien User Interfaces (UI) fokussiert.

Bei Android kann man UI-Tests nativ mithilfe des Frameworks Espresso abbilden. Daneben sind aber auch andere Test Frameworks wie Robotium zu nennen, mit denen ebenfalls die Erstellung von UI-Tests für Android möglich ist.

Espresso

Espresso ist ein Framework von Google, welches speziell für das Testen von Android User Interfaces entwickelt wurde. Es wurde im April 2013 bei der Google Test Automation Conference vorgestellt und im Oktober des selben Jahres für Entwickler zugänglich gemacht. Espresso ermöglicht es, native UI-Tests zu schreiben und so direkt auf Code der Entwicklung zuzugreifen.

Setup

Da es sich bei Espresso um ein natives Framework handelt, ist die Einrichtung vergleichsweise einfach. Im ersten Schritt müssen zunächst die neuesten Versionen der folgenden Dependencies zur build.gradle der Applikation hinzugefügt werden:

androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test:rules:1.0.2'

Außerdem muss der Testrunner in der defaultConfig Sektion der build.gradle ergänzt werden:

testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

Anschließend ist das Setup auch schon abgeschlossen und es kann mit dem Schreiben der Tests begonnen werden.

Tests mit Espresso

In diesem Beispiel soll eine kleine Application getestet werden, die aus zwei Screens besteht. Der erste Screen enthält zwei Buttons, und eine TextView, der zweite Screen enthält eine RecyclerView und einen FloatingActionButton (FAB). Über der Liste soll eine TextView stehen. Für die Umsetzung der Screens wurden zwei Fragments in einer Activity verwendet.
 Die Liste wurde mithilfe einer RecyclerView erstellt.

Klickt man im ersten Screen auf den linken Button, so wird der Counter in der TextView hochgezählt.

Abbildung 1: Ein Klick auf den rechten Button öffnet den zweiten Screen

Abbildung 1: Ein Klick auf den rechten Button öffnet den zweiten Screen

Abbildung 2: Im zweiten Screen soll bei Klick auf den FAB ein Element zur Liste hinzugefügt werden. Ein Element der Liste besteht aus einer TextView und einer Checkbox.

Abbildung 2: Im zweiten Screen soll bei Klick auf den FAB ein Element zur Liste hinzugefügt werden. Ein Element der Liste besteht aus einer TextView und einer Checkbox

In der TextView soll das Element mit Nummer stehen also “Item 0” beim ersten Element, “Item 1” beim zweiten Element usw. Außerdem soll in der TextView über der Liste die Anzahl der Elemente, die ausgewählt sind und die Anzahl der gesamten Elemente angezeigt werden. Das soll wie folgt dargestellt werden: “2/5 elements selected”. Nach Klick auf den „Back“ Button oben links kehrt die Ansicht zum ersten Screen zurück.

Abbildung 3

Abbildung 3

Für diese Applikation werden nun UI-Tests definiert. Der erste Schritt hierfür ist das Anlegen einer Rule für die verwendete Activity.

public class MainActivityTestRule extends ActivityTestRule{

    public MainActivityTestRule(Class activityClass) {

        super(activityClass);
    }
}

Es kann hier auch die Standard ActivityTestRule verwendet werden. Da aber später an dieser Stelle noch etwas überschrieben wird, soll eine eigene Rule für die MainActivity angelegt werden.

Im Anschluss kann nun der erste Espresso Test geschrieben werden. Hierfür legt man eine Klasse im “androidTest” Ordner an, in welchem standardmäßig nach Integration Tests gesucht wird. Da keine extrem große Testklasse benötigt wird, kann eine Klasse für den ersten Screen und eine für den zweiten Screen erstellt werden. Damit die Rule in beiden verwendet werden kann, legt man die “BaseTest“ Klasse an, von der die beiden Testklassen erben können. Anschließend kann eine neue Instanz der Rule angelegt werden:

@Rule
public MainActivityTestRule mActivityRule = new MainActivityTestRule<>(MainActivity.class);

Im nächsten Schritt kann eine Testklasse für den ersten Screen angelegt werden. Diese erbt von „BaseTest“. Mit der Annotation @Test wird nun eine Methode markiert, die einen Test repräsentiert. Es empfiehlt sich, die Testmethoden aussagekräftig zu benennen, damit direkt ersichtlich ist, was genau getestet wird. Bei UI-Tests empfiehlt sich folgende Notation:

test_wasSollImTestPassieren_WasWirdErwartet()

Dieses Vorgehen kann dazu führen, dass die Namen der Testmethoden sehr lange werden, aber erlaubt es dem Entwickler auch ohne Dokumentation schnell einzusehen, was in dieser Methode getestet wird.

Im ersten Test soll überprüft werden, ob die UI mit den richtigen Werten initialisiert wurde:

@Test
public void test_uiHasSetupCorrectly_AllViewsShouldBeVisibleAndHaveCorrectValues(){
    onView(withId(R.id.fragment_button_counter_text_view)).check(
                matches(withText("Number of Button Clicks: 0")));
    onView(withId(R.id.fragment_button_counter_button)).check(matches(withText("Count")));
    onView(withId(R.id.fragment_button_fragment_change_button)).check(
                matches(withText("Change Fragment")));
}

Mit onView() wird die View selektiert, die getestet werden soll. Die id ist die “android:id”, die im XML Layout File für ein UI-Element festgelegt wird. Anschließend wird über check() ein Matcher erwartet. In unserem Fall wird jeweils nur der String verglichen. Hier sollten besser String Resources anstelle von festen Strings verwendet werden. Dies hat zwei Vorteile:

Für die Testapplikation empfiehlt es sich aber, bei festen Strings zu bleiben.

Nun ist sichergestellt, dass der Screen ordentlich aufgebaut wurde. Die nächste Funktion des ersten Screens ist das Klicken auf den linken Button und das Hochzählen des Counters im Textfeld. Neben der Überprüfung eines Elementes wie im vorangegangen Test, kommt hier außerdem das Klicken des Buttons, also eine Action hinzu:

@Test
public test_ButtonClickUpdatesCounter_CounterCountsUp(){
    onView(withId(R.id.first_screen_text_view)).check(matches(withText(“0 Klicks”)));
    onView(withId(R.id.first_screen_left_button)).perform(click());
    onView(withId(R.id.first_screen_text_view)).check(matches(withText(“1 Klicks”)));
}

Zunächst wird geprüft, ob der Anfangswert korrekt ist, anschließend wird über die onView(withId()) der linke Button ausgewählt und über perform() eine Action ausgewählt, die auf dem Objekt ausgeführt werden soll. In unserem Fall ist die Action click().

Anschließend sollte kontrolliert werden, ob der Counter hochgezählt wurde. Auf eine Unterscheidung zwischen Singular und Plural bei einem oder mehreren Elementen wurde hier verzichtet. Um sicherzustellen, dass dies auch mehr als einmal funktioniert, wird ein weiterer Test hinzugefügt, in welchem der Button zehn Mal geklickt wird:

@Test
public test_ButtonClickUpdatesCounter_CounterCountsUp(){
    onView(withId(R.id.first_screen_text_view)).check(
            matches(withText(“0 Klicks”)));
    for(int i = 0; i<10 ; i++{
                onView(withId(R.id.first_screen_left_button)).perform(click());
    }
    onView(withId(R.id.first_screen_text_view)).check(
            matches(withText(“10 Klicks”)));
}

Die click() Action wird nun in einer Schleife zehn mal hintereinander ausgeführt. Im Anschluss erfolgt die Überprüfung, ob korrekt mitgezählt wurde.

Es gibt im ersten Screen noch eine zweite Action, deren korrekte Ausführung mittels eines UI-Tests sichergestellt werden soll. Durch Klick auf den rechten Button soll sich der zweite Screen öffnen.

Um zu testen, ob sich die View tatsächlich geöffnet hat, kann geprüft werden, ob ein Layout Element des zweiten Screens sichtbar ist. Man könnte alternativ auch den Titel der Toolbar oder ein anderes Alleinstellungsmerkmal der View verwenden. In unserem Fall wurde der FAB im zweiten Screen ausgewählt:

@Test
public test_ButtonClickUpdatesCounter_CounterCountsUp(){
    onView(withId(R.id.first_screen_right_button)).perform(click());
    onView(withId(R.id.second_screen_floating_action_button)).check(matches(isDisplayed()));
}

Nach Klick auf den Button im ersten Screen kann der FAB über die Layout-ID gefunden werden und es wird überprüft, ob der Button angezeigt wird.

Nun sind alle Funktionen des ersten Screens abgedeckt. Die Tests für den zweiten Screen werden in der zweiten Testklasse angelegt. Hierbei fällt auf, dass alle Tests zunächst zum zweiten Screen navigieren müssen, bevor sie ausgeführt werden können. Da dies für alle Tests in dieser Testklasse gilt, kann hier die @Before Annotation verwendet und vor jedem Test ausgeführt werden. Andernfalls müsste in jedem Test eine Methode aufgerufen werden, die zum zweiten Screen navigiert.

@Before
public void setUp(){
	onView(withId(R.id.first_screen_right_button)).perform(click());
}

Nun kann mit der Prüfung des zweiten Screens begonnen werden, folgendes sollte getestet werden:

Ein Klick auf den FAB fügt ein Element zur Liste hinzu, die TextView in dem hinzugefügten Element enthält den korrekten Text und die TextView über der Liste hat sich korrekt aktualisiert.

Um die UI im Grundzustand zu überprüfen, muss hier nur der Inhalt der TextView über der Liste und die Sichtbarkeit des FAB überprüft werden.

Nun zum ersten Test, der ein Element einer RecyclerView enthält. Der Klick auf den FAB kann analog zu den Klicks auf die Buttons im ersten Screen realisiert werden. Um ein Element einer RecyclerView zu untersuchen, benötigt man einen eigenen ViewMatcher. Durch eigene ViewMatcher kann man in Espresso nahezu jedes Element untersuchen. Oft gibt es bereits Implementierungen von ViewMatchern für UI Elemente. Für die RecyclerView wurde ViewMatcher verwendet.

Anschließend wird in der „BaseTest“ Klasse eine Methode withRecyclerView() eingeführt, um den Watcher wie die Standard Espresso Matcher aufrufen zu können.

public static RecyclerViewMatcher withRecyclerView(final int recyclerViewId) {
    return new RecyclerViewMatcher(recyclerViewId);
}

Nun können die Elemente der RecyclerView getestet werden. Hierbei sollte man sich angewöhnen, vor dem Testen eines Elements zu dem Index des Elements zu scrollen. Dies ist notwendig, da Espresso nur ein Element testen kann, das auf dem Bildschirm angezeigt wird ist. Um das Scrollen der RecyclerView möglich zu machen, müssen wir nun auch das “espresso-contrib” Repository einbinden. Dieses enthält zusätzliche Möglichkeiten UI-Elemente, zu matchen oder mit ihnen zu interagieren. Wir benötigen für unseren Test diese RecyclerViewActions:

@Test
public void test_clickFAB_itemIsAddedToListTextViewUpdated() {
    onView(withId(R.id.list_fragment_floating_action_button)).perform(click());
    onView(withId(R.id.list_fragment_recycler_view)).perform(RecyclerViewActions.scrollToPosition(0));
    onView(withRecyclerView(R.id.list_fragment_recycler_view).atPosition(0)).check(
            matches(hasDescendant(withText("Item 0"))));
    onView(withId(R.id.list_fragment_title_text_view)).check(matches(withText("0/1 items selected")));
}

Nach dem Klick auf den FAB scrollt man mithilfe der RecyclerViewAction scrollToPosition(index) zum Index der Liste, der überprüft werden soll. Dies ist hier zwar nicht unbedingt notwendig, da das erste Element der List im Normalfall immer sichtbar ist, aber so wird der Schritt auch in anderen Fällen nicht vergessen. Zusätzlich sollte man bedenken, dass das Gerät, mit welchem man entwickelt, nicht zwingend das gleiche Gerät ist, auf dem die Tests ausgeführt werden müssen.

Anschließend kann mithilfe des Matchers auf das Listen Element an der Stelle 0 zugegriffen und überprüft werden, ob eine ihrer Subviews den korrekten Text enthält. Da hier nur ein Element mit dem entsprechenden Text vorgesehen ist, reicht das aus.

Als nächstes soll eine Checkbox angewählt und im Anschluss überprüft werden, ob der Text über der Liste sich korrekt ändert:

@Test
public void test_addElementSelectElementCheckBox_shouldRefreshTextViewCorrectly() {
    onView(withId(R.id.list_fragment_floating_action_button)).perform(click());
    onView(withId(R.id.list_fragment_recycler_view)).perform(RecyclerViewActions.scrollToPosition(0));
    onView(withId(R.id.list_fragment_recycler_view)).perform(
            RecyclerViewActions.actionOnItemAtPosition(0, clickChildViewWithId(R.id.row_list_item_checkbox)));
    onView(withId(R.id.list_fragment_title_text_view)).check(matches(withText("1/1 items selected")));
}

Hier kommt als Neuerung der Klick auf die Checkbox hinzu. Da sich die Checkbox jeweils in einem Listenelement befindet, kann man hier wieder eine RecyclerViewAction verwenden. Mit actionOnItemAtPosition kann ein Index und eine ViewAction mitgegeben werden:

public class ChildClickViewAction {
    public static ViewAction clickChildViewWithId(final int resourceId) {
        return new ViewAction() {
            @Override
            public Matcher getConstraints() {
                return null;
            }

            @Override
            public String getDescription() {
                return "Click on a child view with specified id.";
            }

            @Override
            public void perform(UiController uiController, View view) {
                View v = view.findViewById(resourceId);
                v.performClick();
            }
        };
    }
}

In diesem Fall wird über die ResourceId das entsprechende Element innerhalb der gegebenen View gesucht und auf diese View geklickt. Nach dem Klick auf die Checkbox wird überprüft, ob sich die TextView über der Liste auch entsprechend aktualisiert hat.

Für die letzten Tests werden keine neuen Konzepte mehr benötigt, daher werden sie an dieser Stelle nicht explizit aufgelistet. Beide Tests sind jedoch über Github einsehbar.

Abschließend soll noch geprüft werden, ob die Navigation über den „Zurück“-Button oben links funktioniert. Hierbei ist auf eine Besonderheit zu achten: Leider kann Espresso nicht mit der Id auf den Button zugreifen. Zumindest dann nicht, wenn dieser mit setHomeAsUpEnabled(true) erstellt wurde. Stattdessen wird hierfür eine Description verwendet:

@Test
public void test_pressBackButton_shouldReturnToButtonFragment(){
    onView(withContentDescription(R.string.abc_action_bar_up_description)).perform(click());
    onView(withId(R.id.fragment_button_counter_text_view)).check(matches(isDisplayed()));
}

Um also auf den „Zurück“-Button zu klicken, muss zunächst die Description ermittelt werden. Diese hat eine feste Resource Id, d.h. dieser Test funktioniert auch sprachunabhängig. Im letzten Schritt wird geprüft, ob die TextView im ersten Screen angezeigt wird.

Nun wurde die korrekte Funktionsweise der App fast vollständig mit UI-Tests sichergestellt. Ein spezieller Fall sollte jedoch noch berücksichtigt werden. Bisher würden die Tests nur laufen, wenn das Testgerät entsperrt ist. Bei ausgeschaltetem Bildschirm oder gesperrten Gerät schlagen alle Tests fehl, da die Activity nicht gefunden wird. Daher soll das Gerät entsperrt und den Bildschirm angeschaltet werden, bevor die Tests ausgeführt werden. Hierfür darf das Testgerät keine Sperre wie eine PIN besitzen.

Hierfür müssen wir wider in unser MainActivityTestRule Klasse zurück und das Interface ActivityLifecycleCallback implementieren. Dies ermöglicht es uns die Methode onActivityLifecycleChanged() zu implementieren.

@Override
public void onActivityLifecycleChanged(Activity activity, Stage stage) {
    if (stage == Stage.PRE_ON_CREATE) {
        activity.getWindow()
                .addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                        | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
                        | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON);
    }
}

Hier prüft man, ob sich die Activity im PRE_ON_CREATE Status, also bevor sie erstellt wird, befindet und versucht, den Bildschirm anzuschalten und das Gerät zu entsperren.

Zusätzlich muss die Methode beforeActivityLaunched überschrieben werden, um den Listener zu setzen. So werden die Tests auch bei ausgeschaltetem Bildschirm ausgeführt.

@Override
protected void beforeActivityLaunched() {
    super.beforeActivityLaunched();
    ActivityLifecycleMonitorRegistry.getInstance().addLifecycleCallback(this);
}

Abschließend lässt sich festhalten, dass Espresso ein wertvolles Tool bei der App-Entwicklung für Android ist, dessen Nutzung im Zusammenspiel mit anderen Testarten sehr zu empfehlen ist.

Die gesamte Applikation inklusive aller hier beschriebenen Tests steht auf GitHub zur Verfügung.

Bildnachweis:

  • GettyImages: RapidEye

Weitere Artikel aus unserem Blog

let’s dev Blog | Der World Usability Day 2023

Corporate

Der World Usability Day 2023

by Sina

2023-11-10

Weiterlesen
let’s dev Blog | Adobe Max 2023

Corporate

Adobe Max 2023

by Julia

2023-10-13

Weiterlesen
let’s dev Blog | Barrierefreiheit in der Webentwicklung

Technical

Barrierefreiheit in der Webentwicklung

by Sarah

2023-10-31

Weiterlesen
let’s dev Blog | Digitale Wallet-Karten: Stärkung von Kundenbindung im digitalen Zeitalter

Corporate

Digitale Wallet-Karten: Stärkung von Kundenbindung im digitalen Zeitalter

by Julian

2023-07-07

Weiterlesen
let’s dev Blog | Kortpress auf dem OMR Festival 2023 in Hamburg

Corporate

Kortpress auf dem OMR Festival 2023 in Hamburg

by Julian

2023-05-31

Weiterlesen
let’s dev Blog | Recap 2022: Smart Devices, digitale Plattformen und innovative Forschungsprojekte

Corporate

Recap 2022: Smart Devices, digitale Plattformen und innovative Forschungsprojekte

by Julian

2023-01-31

Weiterlesen
let’s dev Blog | Mit LottieFiles Animationen für das Web erstellen

Corporate

Mit LottieFiles Animationen für das Web erstellen

by Julian

2022-12-15

Weiterlesen
let’s dev Blog | Lean in der Softwareentwicklung

Technical

Lean in der Softwareentwicklung

by Sabrina

2022-12-08

Weiterlesen
let’s dev Blog | Adobe Max - Live aus LA

Corporate

Adobe Max - Live aus LA

by Jessica

2022-10-28

Weiterlesen
let’s dev Blog | Mensch und Computer 2022 - Facing Realities

Corporate

Mensch und Computer 2022 - Facing Realities

by Kerstin

2022-09-12

Weiterlesen
let’s dev Blog | EUREKA Innovation Award

Corporate

EUREKA Innovation Award

by Karl

2022-06-23

Weiterlesen
let’s dev Blog | Die WWDC 2022: Unser Update zu Apples neuen Betriebssystemen

Technical

Die WWDC 2022: Unser Update zu Apples neuen Betriebssystemen

by Julian

2022-06-08

Weiterlesen
let’s dev Blog | Docker und die versteckte Sicherheitslücke

Technical

Docker und die versteckte Sicherheitslücke

by Martin

2022-02-17

Weiterlesen
let’s dev Blog | Die Weihnachtsfeiertage stehen wieder vor der Tür – Wir blicken gespannt auf das nächste Jahr 2022!

Corporate

Die Weihnachtsfeiertage stehen wieder vor der Tür – Wir blicken gespannt auf das nächste Jahr 2022!

by Julian

2021-12-22

Weiterlesen
let’s dev Blog | Fertigung und Montage von Stacks und Elektro­lyseuren für die Wasser­stoff­herstellung

Corporate

Fertigung und Montage von Stacks und Elektro­lyseuren für die Wasser­stoff­herstellung

by Anton

2021-12-21

Weiterlesen
let’s dev Blog | Adobe Max 2021 - Ein Fest der Kreativität

Corporate

Adobe Max 2021 - Ein Fest der Kreativität

by Julia

2021-11-02

Weiterlesen
let’s dev Blog | Relationale Datenbanken im Vergleich zu objektorientierten Datenbanken

Technical

Relationale Datenbanken im Vergleich zu objektorientierten Datenbanken

by Julian

2021-10-14

Weiterlesen
let’s dev Blog | Apple Developer Program: Wofür wird es benötigt und welche Inhalte bieten mir eine Mitgliedschaft?

Corporate

Apple Developer Program: Wofür wird es benötigt und welche Inhalte bieten mir eine Mitgliedschaft?

by Julian

2021-09-30

Weiterlesen
let’s dev Blog | Sketch, Figma & Co - Wir werfen einen Blick auf die beliebtesten UI und Prototyping Tools 2021

Corporate

Sketch, Figma & Co - Wir werfen einen Blick auf die beliebtesten UI und Prototyping Tools 2021

by Ellen

2021-07-15

Weiterlesen
let’s dev Blog | Rückenwind: Ein innovatives Projekt für den Weiterbetrieb von alten Windkraftanlagen

Corporate

Rückenwind: Ein innovatives Projekt für den Weiterbetrieb von alten Windkraftanlagen

by Karl

2021-06-24

Weiterlesen
let’s dev Blog | Features, Fixes und Funktionen - Ein Sumup der WWDC 2021

Corporate

Features, Fixes und Funktionen - Ein Sumup der WWDC 2021

by Julian

2021-06-10

Weiterlesen
let’s dev Blog | Smart Prognosis of Energy with Allocation of Resources

Corporate

Smart Prognosis of Energy with Allocation of Resources

by Karl

2021-02-18

Weiterlesen
let’s dev Blog | Dasoman - Daten-Souveränitäts-Manager

Corporate

Dasoman - Daten-Souveränitäts-Manager

by Karl

2021-01-11

Weiterlesen
let’s dev Blog | Wir blicken auf die vergangenen Monate zurück – Und wünschen alles Gute für das kommende Jahr 2021!

Corporate

Wir blicken auf die vergangenen Monate zurück – Und wünschen alles Gute für das kommende Jahr 2021!

by Julian

2020-12-17

Weiterlesen
let’s dev Blog | iOS User Interface Tests

Technical

iOS User Interface Tests

by Nicolas

2020-11-12

Weiterlesen
let’s dev Blog | Adobe Max - Zum ersten Mal online

Corporate

Adobe Max - Zum ersten Mal online

by Julia

2020-10-29

Weiterlesen
let’s dev Blog | CAN2BLE

Technical

CAN2BLE

by Raphael

2020-09-24

Weiterlesen
let’s dev Blog | Mensch und Computer 2020 - Digitaler Wandel im Fluss der Zeit

Corporate

Mensch und Computer 2020 - Digitaler Wandel im Fluss der Zeit

by UX Team

2020-09-18

Weiterlesen
let’s dev Blog | Neumorphism – Eine neue Ära des User Interface Design?

Technical

Neumorphism – Eine neue Ära des User Interface Design?

by Julian

2020-08-13

Weiterlesen
let’s dev Blog | UX Research Teil 3 – UX Methoden

Technical

UX Research Teil 3 – UX Methoden

by Elena

2020-05-28

Weiterlesen
let’s dev Blog | UX Research Teil 2 - Was ist UCD und was hat User Research damit zu tun?

Technical

UX Research Teil 2 - Was ist UCD und was hat User Research damit zu tun?

by Elena

2020-04-23

Weiterlesen
let’s dev Blog | go-digital fördert Einrichtung von Home Office Arbeitsplätzen

Corporate

go-digital fördert Einrichtung von Home Office Arbeitsplätzen

by Karl

2020-03-19

Weiterlesen
let’s dev Blog | Google Passes - Karten­verwaltung auf  Android-Geräten

Technical

Google Passes - Karten­verwaltung auf Android-Geräten

by Michelle

2020-03-12

Weiterlesen
let’s dev Blog | 100% Code-Coverage bei Software Tests – eine sinnvolle Zielsetzung?

Technical

100% Code-Coverage bei Software Tests – eine sinnvolle Zielsetzung?

by Raphael

2020-03-06

Weiterlesen
let’s dev Blog | Swift UI - Einfache und schnelle Umsetzung von User Interfaces

Technical

Swift UI - Einfache und schnelle Umsetzung von User Interfaces

by Tobias

2020-03-02

Weiterlesen
let’s dev Blog | Im Dialog mit den Wirtschafts­junioren – Spannende Einblicke in die Unternehmens­gründung und die digitale Trans­formation

Corporate

Im Dialog mit den Wirtschafts­junioren – Spannende Einblicke in die Unternehmens­gründung und die digitale Trans­formation

by Julian

2020-02-27

Weiterlesen
let’s dev Blog | Vereinfachtes Testen von iOS Push Notifications im Simulator mit Xcode 11.4

Technical

Vereinfachtes Testen von iOS Push Notifications im Simulator mit Xcode 11.4

by Manuel

2020-02-26

Weiterlesen
let’s dev Blog | Nationales Meeting des Konsortiums des SPEAR Forschungs­projektes bei let’s dev in Karlsruhe

Corporate

Nationales Meeting des Konsortiums des SPEAR Forschungs­projektes bei let’s dev in Karlsruhe

by Karl

2020-01-27

Weiterlesen
let’s dev Blog | UX Research Teil 1 – Warum User Research so wichtig ist

Technical

UX Research Teil 1 – Warum User Research so wichtig ist

by Elena

2020-01-23

Weiterlesen
let’s dev Blog | Dark Mode

Technical

Dark Mode

by Elisa

2020-01-09

Weiterlesen
let’s dev Blog | Wir wünschen frohe Weihnachten – Und einen guten Start ins neue Jahr!

Corporate

Wir wünschen frohe Weihnachten – Und einen guten Start ins neue Jahr!

by Julian

2019-12-20

Weiterlesen
let’s dev Blog | Austausch zum Thema Digitalisierung mit dem Business Club Luxemburg in der Botschaft von Luxemburg in Berlin

Corporate

Austausch zum Thema Digitalisierung mit dem Business Club Luxemburg in der Botschaft von Luxemburg in Berlin

by Karl

2019-12-17

Weiterlesen
let’s dev Blog | DaSoMan auf der Internet+ Expo in Foshan (China)

Corporate

DaSoMan auf der Internet+ Expo in Foshan (China)

by Karl

2019-12-13

Weiterlesen
let’s dev Blog | Google Play Console: Pre-Launch Berichte

Technical

Google Play Console: Pre-Launch Berichte

by Fabian

2019-12-11

Weiterlesen
let’s dev Blog | DevFest 2019 in Hamburg

Technical

DevFest 2019 in Hamburg

by Julian

2019-12-05

Weiterlesen
let’s dev Blog | Vernissage digitale Kunst im Medientheater der Humboldt Universität Berlin

Corporate

Vernissage digitale Kunst im Medientheater der Humboldt Universität Berlin

by Karl

2019-11-21

Weiterlesen
let’s dev Blog | World Usability Day 2019 in Karlsruhe – let’s dev unterstützt als Hauptsponsor

Corporate

World Usability Day 2019 in Karlsruhe – let’s dev unterstützt als Hauptsponsor

by Aileen

2019-11-11

Weiterlesen
let’s dev Blog | Ausgeschlachtet - Tag der offenen Türen auf dem Alten Schlachthof Karlsruhe 2019

Corporate

Ausgeschlachtet - Tag der offenen Türen auf dem Alten Schlachthof Karlsruhe 2019

by Julian

2019-09-26

Weiterlesen
let’s dev Blog | Mensch und Computer 2019 - Konferenz zu User Experience und Usability in Hamburg

Corporate

Mensch und Computer 2019 - Konferenz zu User Experience und Usability in Hamburg

by Elena

2019-09-17

Weiterlesen
let’s dev Blog | Business und Enterprise App Verteilung unter iOS

Technical

Business und Enterprise App Verteilung unter iOS

by Aileen

2019-08-05

Weiterlesen
let’s dev Blog | Digital Transformation - Chances and Challenges in the Automotive Industry, Agriculture and New Technologies

Corporate

Digital Transformation - Chances and Challenges in the Automotive Industry, Agriculture and New Technologies

by Karl

2019-07-17

Weiterlesen
let’s dev Blog | let’s dev unterstützt Läuferinnen und Läufer bei der 7. KIT Meisterschaft

Corporate

let’s dev unterstützt Läuferinnen und Läufer bei der 7. KIT Meisterschaft

by Karl

2019-07-05

Weiterlesen
let’s dev Blog | Automatisiertes Testing von C++ Code mit Google Test und Google Mock – Teil 2

Technical

Automatisiertes Testing von C++ Code mit Google Test und Google Mock – Teil 2

by Arne

2019-06-13

Weiterlesen
let’s dev Blog | Apple WWDC 2019: Das sind die Highlights der Keynote

Technical

Apple WWDC 2019: Das sind die Highlights der Keynote

by Nicolas

2019-06-05

Weiterlesen
let’s dev Blog | App Builders 2019

Technical

App Builders 2019

by Nicolas

2019-05-23

Weiterlesen
let’s dev Blog | Offizielle Eröffnung des Festigungs- und Expansionszentrums (FUX)

Corporate

Offizielle Eröffnung des Festigungs- und Expansionszentrums (FUX)

by Helena

2019-04-15

Weiterlesen
let’s dev Blog | Delegation aus Nottingham zu Besuch auf dem Alten Schlachthof in Karlsruhe

Corporate

Delegation aus Nottingham zu Besuch auf dem Alten Schlachthof in Karlsruhe

by Helena

2019-04-14

Weiterlesen
let’s dev Blog | Es ist soweit: Wir ziehen um!

Corporate

Es ist soweit: Wir ziehen um!

by Helena

2019-03-26

Weiterlesen
let’s dev Blog | Automatisiertes Testing von C++ Code mit Frameworks – Teil 1

Technical

Automatisiertes Testing von C++ Code mit Frameworks – Teil 1

by Arne

2019-02-20

Weiterlesen
let’s dev Blog | Die App im Google Play Store

Technical

Die App im Google Play Store

by Elisa

2019-01-24

Weiterlesen
let’s dev Blog | „UX Day“ 2018

Corporate

„UX Day“ 2018

by Aileen

2018-12-17

Weiterlesen
let’s dev Blog | let’s dev unterstützt SG Siemens Volleyballer aus Karlsruhe

Corporate

let’s dev unterstützt SG Siemens Volleyballer aus Karlsruhe

by Helena

2018-12-04

Weiterlesen
let’s dev Blog | KMU gestalten die Digitalisierung – Mittelstandskonferenz 2018

Corporate

KMU gestalten die Digitalisierung – Mittelstandskonferenz 2018

by Helena

2018-11-12

Weiterlesen
let’s dev Blog | Apple Wallet

Technical

Apple Wallet

by Maik

2018-10-26

Weiterlesen
let’s dev Blog | „Mensch und Computer“ 2018

Corporate

„Mensch und Computer“ 2018

by Judith

2018-09-24

Weiterlesen
let’s dev Blog | State Design Pattern in Android

Technical

State Design Pattern in Android

by Thomas

2018-09-17

Weiterlesen
let’s dev Blog | let’s dev ist autorisiertes Beraterunternehmen im Förderprogramm „go-digital“

Corporate

let’s dev ist autorisiertes Beraterunternehmen im Förderprogramm „go-digital“

by Helena

2018-09-01

Weiterlesen
let’s dev Blog | App Design & Development Conference 2018

Corporate

App Design & Development Conference 2018

by Helena

2018-08-14

Weiterlesen
let’s dev Blog | iOS 12: Die Top-Neuerungen im Überblick

Technical

iOS 12: Die Top-Neuerungen im Überblick

by Nicolas

2018-07-17

Weiterlesen
let’s dev Blog | let’s dev auf der CEBIT

Corporate

let’s dev auf der CEBIT

by Karl

2018-06-11

Weiterlesen
let’s dev Blog | Die App im Apple App Store: welche Informationen werden benötigt?

Technical

Die App im Apple App Store: welche Informationen werden benötigt?

by Aileen

2018-04-27

Weiterlesen
let’s dev Blog | Smart Pointer in C++

Technical

Smart Pointer in C++

by Matthias

2018-04-01

Weiterlesen
let’s dev Blog | User Interface Design für das iPhone X: alle Neuerungen auf einen Blick

Technical

User Interface Design für das iPhone X: alle Neuerungen auf einen Blick

by Helena

2018-02-07

Weiterlesen
let’s dev Blog | WebVR – Virtual Reality Experience im Browser mit dem A-Frame Framework

Technical

WebVR – Virtual Reality Experience im Browser mit dem A-Frame Framework

by Judith

2018-01-10

Weiterlesen
let’s dev Blog | Open Data Hackathon der Deutschen Bahn

Corporate

Open Data Hackathon der Deutschen Bahn

by Karl

2015-03-31

Weiterlesen
let’s dev Blog | Blur-Effekte unter iOS 7

Technical

Blur-Effekte unter iOS 7

by Katja

2014-04-24

Weiterlesen
let’s dev Blog | Beyond App Store – Distribution von iOS-Anwendungen

Technical

Beyond App Store – Distribution von iOS-Anwendungen

by Karl

2012-08-27

Weiterlesen
let’s dev Blog | Frontend-Architektur – Model View Presenter und Message Bus

Technical

Frontend-Architektur – Model View Presenter und Message Bus

by Karl

2011-03-08

Weiterlesen