Projekt A/B testing – update

Po urlopowej przerwie czas na powrót do projektu. Teraz skupiam się głównie na udoskonalaniu kodu, który dotychczas napisałam.

Udało mi się z naprawić funkcję detectUserAgent(), która zwraca string z nazwą przeglądarki z której korzysta użytkownik. Sprawdzam czy jest to Chrome, Firefox, Opera, Edge czy Safari, a w pozostałych przypadkach zwracam string ‚unknown’. Wynik zapisuję w obiekcie z informacjami o użytkowniku.

W mojej bibliotece jest możliwość przeprowadzania testów AB na określonej przeglądarce. Wystarczy wpisać jako argument funkcji testOnParticularUserAgent() nazwę przeglądarki na której chcemy przeprowadzić test oraz nazwę funkcji, która ma zostać wykonana. Czyli np. testOnParticularUserAgent(chrome, testColor) – funkcja ta testuje tylko i wyłącznie na Chromie background color danego elementu.  Natomiast funkcja testColor() przymuje trzy argumenty: colorA, colorB i id elementó który chcemy testować.

Dodatkowo stworzyłam funkcję umożliwiającą wykonywanie testów na określonych rozdzielczościach ekranu.  testOnScreensBetweenWidths() przyjmuje trzy argumenty:  minimalną szerokość na której chcemy testować, maksymalną szerokość oraz jako trzeci argument wskazujemy funkcję, która ma zostać wykonana w razie spełnienia warunków.  W przypadku, gdy warunek nie jest spełniony, w local storage zapisuję informację w postaci stringa.

I jeszcze jedna ważna rzecz, czyli funckja eventLister(). Na każdym elemencie który jest testowany dodawany jest event listener, który informuje o tym czy ten element został kliknięty, a informacja o tym zapisywana jest w local storage.

W przyszłym tygodniu nadal namierzam udoskonalać mój kod. To jest mój 19. konkursowy wpis na moim blogu (w ramach konkursu DajSięPozać 2017). Jestem bardzo zadowolona, że wzięłam w nim udział i już prawie udało mi się spełnić wszystkie wymagania – czyli blogowanie i rozwijanie projektu przez min. 10 tygodni. Bardzo dużo się nauczyłam i dzięki temu zrobiłam postęp w nauce JSa i nie tylko. Była i jest to dla mnie spora motywacja. Wielkie dzięki dla organizatora konkursu Macieja Aniserowicza z bloga Devstyle. Na prawdę świetna inicjatywa! 

Projekt AB Testing – ciąg dlaszy

W tym tygodniu, udało mi się dodać kawałki kodu, które zapisują wynik jednego testu w localStorage. Zapisuję czy test został wykonany, który element na stronie jest testowany oraz która z opcji została wylosowana. Dodatkowo, mam uniwersalną funkcję, która nasłuchuje na kliknięcia na elemencie o danym ID. Gdy dany element zostaje kliknięty, dodaję o tym informację w localStorage. Na poniższym screen shotcie, możemy zobaczyć wynik jednego z testów.

local-storage-ABtesting

Docelowo, funkcja testująca będzie egzekwowana tylko raz w jednej sesji. Dlatego, będę też musiała pobierać informacje z localStorage, gdy np. użytkownik zamknie kartę. W tym tygodniu zaczęłam pisać funkcję, która wykrywa przeglądarkę z której korzysta użytkownik strony. Wymaga ona jeszcze dopracowania. Dodatkow chcę napisać fukcję wykrywającą system operacyjny i zapisywać te wyniki w obiekcie z informacjami o użtykowniu. Będę to wykorzysywać do egzekwowania testów warunkowych.

 

Uzyskiwanie infomracji o użytkowniku JS

W moim projekcie AB Testing udało mi się wprowadzić  funkcjonalność pozwalającą na zaciąganie danych o użytkowniku i jego przeglądarce. Nigdy wcześniej tego nie robiłam, dlatego wymagało to początkowego researchu. Wynik na razie loguję w konsoli w postaci obiektu. Dzięki temu możemy sprawdzić kiedy użytkownik otworzył naszą stronę, jaki jest jego język w przeglądarce oraz jakie wymiary ma jego okno przeglądarki. Możemy też sprawdzić z jakiej przeglądarki korzysta. Na razie sprawdzam czy jest to Chrome, Firefox czy Safari.

infomration about user

Dodatkowo mam już wstępną wersję funkcji, która pozwoli na losowanie testowanych elementów tylko raz w podczas jednej sesji, a nie na odświeżeniu karty. Z kolei informacje o kliknięciach będę musiała zapisywać w local storage, ponieważ te dane nie są usuwane po zamknięciu sesji. Pomyślałam, że fajna byłaby możliwość testowania pewnych elementów na stronie, jeśli zostanie spełniony określony warunek np. tylko na użytkownikach Androida, albo na użytkownikach, których ekran ma większą rozdzielczość niż X pixeli. Do tych celów będę korzystać z danych, które zaciągam o użytkowniku. Będzie to kolejna rzecz, którą chciałabym zrealizować w tym projekcie.

 

 

Kolejne kroki związane z projektem – Testy A/B

Na stronie wszystkie elementy są testowane niezależnie od siebie. Testuje kolor buttona, display buttona, tekst, obraz, kolor tekstu oraz film. Losowanie odbywa się na odświeżeniu karty.

AB testing - wynik losowania
Wynik losowania
AB testing - wynik losowania
Wynik losowania
AB testing - wynik losowania
Wynik losowania

Wreszcie udało mi się znaleźć błąd w kodzie. Poprawiłam obydwie uniwersalne funkcje. Jedna pozwala na wybranie CSS property i testowanie dwóch wariantów np. jeden z dwóch kolorów czcionki, jednego z kolorów tła, display. Druga funkcja pozwala na np. losowanie jednej z dwóch ścieżek do obrazka bądź filmu, a także na testowanie treści tekstu na stronie.

function drawOneCssProperty(whatToTest, optionA, optionB, elementId) {
  const testedElement = document.getElementById(elementId);
  var randomNumber = Math.random();
  if (randomNumber < 0.5) {
    testedElement.style[whatToTest] = optionA;
  } else {
    testedElement.style[whatToTest] = optionB;
  }
}

function drawOneOption(whatToTest, optionA, optionB, elementId) {
  const testedElement = document.getElementById(elementId);
  var randomNumber = Math.random();
  if (randomNumber < 0.5) {
    testedElement[whatToTest] = optionA;
  } else {
    testedElement[whatToTest] = optionB;
  }
}

A tutaj poniżej wywołuje funkcje. Testowane argumenty są przekazywane w osobnym pliku.

function testColor(colorA, colorB, elementId) {
    drawOneCssProperty('backgroundColor', colorA, colorB, elementId);
}

function testTextColor(colorA, colorB, elementId) {
    drawOneCssProperty('color', colorA, colorB, elementId);
}

function testDisplay(elementId) {
    drawOneCssProperty('display', 'none', 'inline-block', elementId);
}

function testTekst(textA, textB, elementId) {
    drawOneOption('innerHTML', textA, textB, elementId);
}

function testImage(imageSrcA, imageSrcB, elementId) {
    drawOneOption('src', imageSrcA, imageSrcB, elementId);
}

function testIframe(iframeSrcA, iframeSrcB, elementId) {
    drawOneOption('src', iframeSrcA, iframeSrcB, elementId);
}

function testVideo(videoSrcA, videoSrcB, elementId) {
    drawOneOption('src', videoSrcA, videoSrcB, elementId);
}

export { testColor,  testTekst, testImage, testDisplay, testTextColor, testIframe, testVideo};

Co dalej? 

  1. Będę przechowywać informacje o wynikach losowania w local storage.
  2. Zamierzam pobrać informacje o użytkowniku, który wejdzie na testowaną stronę.
  3. Testowanie nie na odświeżeniu strony, ale na jednej sesji
  4. Będę nasłuchiwać na eventy – czyli sprawdzać czy użytkownik podjął akcje na stronie np. kliknął na button, odtworzył wideo za pomocą uniwersalnej funkcji, która pozwoli na nasłuchiwanie na dowolnym elemencie strony.
  5. Będę badać jak wpływa zmiana jednego elementu na inny, czyli np. jak zmiana obrazu na stronie będzie wpływać na klikalność buttona. Do tego będzie potrzebna funkcja, w której będzie trzeba podać id testowanego elementu oraz id elementu na którym badamy ilość eventów.

Projekt jakoś ciężko idzie…

To już piąty tydzień blogowania. Szczerze mówiąc, projekt idzie trochę opornie, nie ma za bardzo czym się chwalić w tym tygodniu… Zdecydowanie łatwiej przychodzi mi pisanie postów nie związanych z projektem. Często przychodzą mi go głowy nowe na tematy artykułów – zapisuję je i powoli realizuję.

Co z projektem? Ameryki nie odkryłam, ale zrobiłam mały krok do przodu.

  1. Napisałam kawałek kodu do testowania filmów. Wcześniej nie miałam jeszcze okazji wstawiać filmów na stronę, więc jest to dla mnie mała nowość, dowiedziałam się kilku ciekawych rzeczy. Na początku skorzystałam z tagu <iframe>, który pozwala na wstawienie kawałka innej strony internetowej do naszej strony. YouTube w łatwy sposób udostępnia już gotowe kawałki kodu (udostępnij -> umieść na stronie -> gotowy kawałek kodu). Drugim sposobem na wstawienia filmu jest użycie tagu <video>.  Tutaj nie korzystamy z linka tylko podajemy ścieżkę do naszego pliku wideo. Dodatkowo, mamy też kilka opcji: możemy zapętlić, wyciszyć, a także odtworzyć film automatycznie.
  2. Co do uniwersalnej funkcji, która ma służyć optymalizacji – mam wrażenie, że mnie blokuje – miałam moment oświecenia w tym tygodniu (w czasie powtarzania wiedzy na rozmowę kwalifikacyjną), próbowałam innego podejścia, ale dalej mi coś nie trybi. Obiecuję, że posiedzę nad tym w przyszłym tygodniu.

 

Rozwój projetku AB-Testing

W tym tygodniu:

  1. Napiałam dwa kolejne kawałki kodu służące do testowania display elementu oraz koloru czcionki
  2. Odizolowałam kod biblioteki do oddzielnego pliku
  3. Zdecydowałam się pisać kod w czystym JS, żeby mój program był bardziej uniwersalny
  4. Zaczęłam stosować elementy ES6
  5. Pracuję jeszcze nad optymalizacją kodu – sporo rzeczy się w nim powtarza, dlatego chciałabym napisać jedną ogólną i uniwersalną funkcję, którą będzie można wykorzystać we wszystkich metodach.
  6. Postawiłam środowisko deweloperskie na moim drugim komputerze. Na Ubuntu zainstalowałam Node.js, Ruby, Git oraz nowy edytor VS Code (wcześniej korzystałam z Atoma).

Setup projektu „AB Testing”- Webpack i Webpack DevServer

W tym tygodniu byłam na wykładzie organizowanym przez IT Akademia j-labs pod tytułem “Webpack, czyli mniej znaczy więcej”. Prelegent, Jakub Pikoń, opowiadał o narzędziu deweloperskim Webpack oraz przeprowadził sesję live coding, podczas której zademonstrował jak z niego korzystać. 

Dowiedziałam się, co to jest bundle (duży plik, który powstaje po przez połączenie małych plików) oraz że Webpack jest narzędziem, który jest module bundlerem, czyli umożliwia automatyczne budowanie plików bundle.

Zdecydowałam się na skorzystanie z Webpacka w moim projekcie. Do jego instalacji użyłam NPM. Następnie trzeba było go skonfigurować. Było to dla mnie dość trudne zadanie, dlatego poprosiłam o pomoc mojego znajomego. Pobraliśmy też kompilator Babel, który umożliwia pisanie JS przy użyciu ES6 oraz kilka innych loaderów.

Zainstalowaliśmy również Webpack DevServer co umożliwiło śledzenie zmian w kodzie w czasie rzeczywistym. Teraz już wszystko jest gotowe i mogę już skupić się na tworzeniu mojej biblioteki do testów AB.

 

Losowanie jednego z dwóch kolorów, nagłówków i obrazków

Jak to czasami z projektami bywa, często nie wiemy jak się za nie zabrać, dlatego zwlekałam parę dni z napisaniem jakiejkolwiek linii kodu. Kontuzja kostki skutecznie mnie unieruchomiła i zmusiła do siedzenia (przed monitorem). Odpaliłam Codepena i zaczęłam się zastanawiać. Zdecydowałam, że spróbuję stworzyć skrypt, który będzie losował jeden z dwóch danych kolorów. Pisałam już kiedyś program, który randomowo losował kolor na kliknięciu, ale cel mojego skryptu był inny. Poprosiłam wujka Googla o podpowiedź.

Jak wylosować jedną z dwóch liczb używając JavaScriptu?

How to decide between two numbers randomly using JavaScript?

Na StackOverflow (portal na którym programiści publikują swoje problemy, a inni pomagają im w ich rozwiązaniach) znalazłam dokładnie to co było mi potrzebne. Plan był taki:

  1. Wylosuj randomową liczbę [0, 1) używając Math.random()
  2. Przypisz ją do zmiennej
  3. Jeśli wylosowana liczba będzie mniejsza od 0,5 wybierz wartość 1.
  4. W pozostałych przypadkach wybierz wartość 2.

Udało mi się na początku napisać skrypt w jQuery, następnie w czystym JavaScript. Cóż za satysfakcja! Tego samego dnia udało mi się napisać skrypt losujący treść nagłówka oraz obrazek. Przyjęłam założenie, że w tym samym czasie może być testowany tylko jeden element danego rodzaju. Wybierany on jest za pomocą odpowiedniego ID. Będę jeszcze usprawniać ten kod. Jeśli chcesz zerknąć na najnowszą wersję tego kodu zapraszam na razie na mojego Codepena.

screenshot from Codepen
Każdy element losuje się osobno na odświeżeniu przeglądarki

 

screenshot from Codepen
Wynik kolejnego losowania

Problemy:  

Nie wiem jeszcze jak połączyć Gita z Githubem, dlatego zaczęłam programować w Codepenie. Jeszcze większy problem mam z komputerem, ponieważ mam za mało pamięci i nie mogę niczego zainstalować, co utrudnia całą sprawę.

 

 

Mój program do testów A/B – faza przygotowania i planowania

A/B tests image

W ramach konkursu Daj się Poznać 2017 zdecydowałam się napisać swój własny opensourcowy program, który umożliwi przeprowadzanie testów A/B na stronach internetowych. Zaczęłam od przeczytania pełnej interesujących przykładów książki pt. “Testy A/B od kliknięcia do klienta”, której autorami są: Dan Siroker i Pete Koomen.

Następnie wypisałam elementy które można testować na stronach internetowych:

  1. tekst
  2. kolor tekstu, buttonów, linków
  3. display
  4. większe elementy layoutu
  5. obrazy
  6. wideo
  7. ilość pól w formularzu
  8. kolejność elementów
  9. położenie elementu
  10. inne: font-size, font-family, border-radius itd.

Założyłam również konto i repozytorium na GitHubie (po raz pierwszy sama!). Zaczęłam się zastanawiać co będę potrzebować do dalszej pracy. Zamierzam używać JavaScript oraz jQuery. Żeby przeprowadzać testy będę musiała losowo wybierać jeden z testowanych wariantów.

Testowanie testów – czyli jak będę sprawdzać czy mój program działa dobrze?

Z książki pt. “Testy A/B od kliknięcia do klienta” wyciągnęłam bardzo cenną radę. Jak sprawdzić czy mój program działa prawidłowo? Będę musiała przeprowadzić Test A/A – czyli testować dwa takie same warianty. Jeśli wyniki będą do siebie zbliżone będzie to oznaczać, że kod działa prawidłowo.

Testy A/B – co to takiego?

Testy A/B zaczynają się od prostego pytania:

W jaki sposób mogę poprawić konwersję na mojej stronie internetowej / aplikacji?

Innymi słowy: 

Jak zwiększyć odsetek ludzi, którzy na naszej stronie np. wypełnią formularz, zapiszą się na newsletter, kupią nasz produkt, przekażą darowiznę?

W rozwiązaniu tego problemu przychodzą testy A/B. Polegają one na wyświetlaniu użytkownikom w tym samym czasie różnych wersji poszczególnych elementów strony internetowej i porównywaniu wyników określonego wcześniej współczynnika. Ważne jest aby użytkownicy byli z tej samej grupy docelowej, aby wyniki były jak najmniej zaburzone.

Ciekawostka: Zespół Baracka Obamy korzystał z testów A/B podczas kampanii prezydenckich, oczywiście jak wszystkim wiadomo końcowy rezultat był pozytywny.

A/B tests image
Frangemnt książki „Testy A/B od kliknięcia do klineta”

Istnieje wiele platform, które umożliwiają przeprowadzanie testów A/B np.: https://www.optimizely.com. Ja natomiast w ramach nauki programowania JavaScript i jQuery postanowiłam napisać swój program, który będzie do tego służył. Przez najbliższe kilka tygodni będziecie mogli śledzić moje postępy w pracy.