slawek kluz - ewolucja modelu danych w testach funkcjonalnych – case study

23
Ewolucja modelu danych w testach funkcjonalnych - case study Sławomir Kluz

Upload: kraqa

Post on 24-Jan-2017

588 views

Category:

Engineering


1 download

TRANSCRIPT

Page 1: Slawek Kluz - Ewolucja modelu danych w testach funkcjonalnych – case study

Ewolucja modelu danych w testach funkcjonalnych -

case studySławomir Kluz

Page 2: Slawek Kluz - Ewolucja modelu danych w testach funkcjonalnych – case study

Architektura- mikroserwisy- rest/json- event procesory- zewnętrzni dostawcy- aplikacje klienckie- CI/CD- ~ 40 serwerów

microservice 01

microservice 03

microservice 02

microservice 05

microservice 06

microservice 04

microservice 07

postgresql apache kafka couchbase redis

microservice 08

website backoffice

proxy

Page 3: Slawek Kluz - Ewolucja modelu danych w testach funkcjonalnych – case study

Testy● API: spójność danych, szybki feedback, wpływ na integracje + CD● website/backoffice - selenium● testy wydajnościwe API

Page 4: Slawek Kluz - Ewolucja modelu danych w testach funkcjonalnych – case study

Wersja 1.0● start projektu - testy API● gatling jako framework testowy (testy funkcjonalne + wydajnościowe)● model danych

○ tekst/mapy

Page 5: Slawek Kluz - Ewolucja modelu danych w testach funkcjonalnych – case study

object Account {

val fullBody = """{ "password": "${password}", "email": "${email}", "nickName": "${nickName}", "birthDate": "${birthDate}", "phone": "${phone}", "street": "${street}" }"""

val updateBody = """{ "id":${accountId}, "password": "${password}", "email": "${email}", "nickName": "${nickName}", "birthDate": "${birthDate}", "phone": "${phone}", "street": "${street}" "revision": ${accountRevision} }"""

val incompleteBodyMissingEmail = """{ "password": "${password}", "nickName": "${nickName}", "birthDate": "${birthDate}", "phone": "${phone}", "street": "${street}" }"""}

Page 6: Slawek Kluz - Ewolucja modelu danych w testach funkcjonalnych – case study

Wersja 1.0● start projektu - testy API● gatling jako framework testowy (testy funkcjonalne + wydajnościowe)● model danych

○ tekst/mapy○ json wrapper

Page 7: Slawek Kluz - Ewolucja modelu danych w testach funkcjonalnych – case study

object ParticipantDataFeeder {

private val dataString = """{ |"name":"Arsenal", |"sport": { | "id" : "football", | "name" : "Football" |}, |"metadata":{ | "name":"Arsenal", | "type":"team" | } |}""".stripMargin

def correctData = dataString

def updateWithoutMetadata = new jsonBody(dataString).remove("metadata").get

def withName(name: String) = new jsonBody(dataString).set("name", name).get

def withSport(sport: String) = new jsonBody(dataString).setJson("sport", sport).get

def withoutMetadata = new jsonBody(dataString).remove("metadata").get

}

Page 8: Slawek Kluz - Ewolucja modelu danych w testach funkcjonalnych – case study

private val testScenario: PopulatedScenarioBuilder = scenario(getClass.getSimpleName) .exec(Session.rootAuthenticationToken(Some(testUniverse)) .exec(Participant.put("spin","star",UUID.randomUUID().toString, ParticipantDataFeeder.withoutMetadata, status.in(200,201), jsonPath("$.metadata.name").notExists, jsonPath("$.metadata.type").notExists )) ).inject(performanceStrategy)

Page 9: Slawek Kluz - Ewolucja modelu danych w testach funkcjonalnych – case study

Wersja 1.0● zalety

○ szybkość tworzenia○ możliwość użycia w innych narzędziach○ zrozumiałe dla nietechnicznej osoby

● problemy○ ciężkie do utrzymania przy zmieniającym się modelu, powiązaniu danych i dużej ilości testów○ ciężkie do użycia poza frameworkiem testowym

Page 10: Slawek Kluz - Ewolucja modelu danych w testach funkcjonalnych – case study

Nowe wymagania● powstają aplikacje webowe

○ test są dość wolne - problem przy CI/CD○ nie wszystkie dane da się stworzyć z użyciem strony internetowej○ użycie API do przygotowania danych

● narzędzia○ potrzeba narzędzi do analizy danych

● problemy z frameworkiem testowym○ dość wolne wdrożenie○ brak wsparcia IDE

Page 11: Slawek Kluz - Ewolucja modelu danych w testach funkcjonalnych – case study

Wersja 2.0● struktura kodu projektu - sbt

Page 12: Slawek Kluz - Ewolucja modelu danych w testach funkcjonalnych – case study
Page 13: Slawek Kluz - Ewolucja modelu danych w testach funkcjonalnych – case study

Wersja 2.0● zmiana frameworka testowego● tests-model

○ proste klasy opisujące model danych request/response nie związane z żadnym frameworkiem testowym

○ zależności pomiędzy obiektami○ samplery: przykładowe obiekty w danym stanie

Page 14: Slawek Kluz - Ewolucja modelu danych w testach funkcjonalnych – case study

case class ChatMessage( `type`: String, content: MessageContent, sender: Option[AccountReference] = None, tags: Option[Array[String]] = None, sentAt: Option[String] = None)

case class AccountReference(id: Int, `type`: String, name: String)

case class MessageContent(text: String)

Page 15: Slawek Kluz - Ewolucja modelu danych w testach funkcjonalnych – case study

object PaymentMethodSampler {

def creditCardPayment = PaymentMethod( provider = Some("realex"), `type` = Some("credit-card") )

def invalidProviderPayment = PaymentMethod( provider = Some("polcard"), `type` = Some("credit-card") )

Page 16: Slawek Kluz - Ewolucja modelu danych w testach funkcjonalnych – case study

Wersja 2.0● tests-api

○ serializacja/deserializacja obiektów modelu○ wbudowany mechanizm z rest-assured ○ warstwa “serwisów”

Page 17: Slawek Kluz - Ewolucja modelu danych w testach funkcjonalnych – case study

object ChatService {

val _sendMessage = " /chats/{universe}/{chatType}/{chatId}/messages"

def sendMessage(session: Session, universe: String, chatType: String, chatId: String, message: AnyRef) = { given() .specification(Specifications.authorizedExternal(session)) .pathParam("universe", universe) .pathParam("chatType", chatType) .pathParam("chatId", chatId) .body(message) .when() .post(_sendMessage) .Then() .assertThat() .statusCode(200) }}

Page 18: Slawek Kluz - Ewolucja modelu danych w testach funkcjonalnych – case study

def chatWithHistory(session: Session, universe: String, chatType: String, chatId: String): ChatHistory = { given() .specification(Specifications.authorizedExternal(session)) .pathParam("universe", universe) .pathParam("chatType", chatType) .pathParam("chatId", chatId) .when() .get(_chatWithHistory) .Then() .assertThat() .statusCode(200) .extract().body().as(classOf[ChatHistory]) }

Page 19: Slawek Kluz - Ewolucja modelu danych w testach funkcjonalnych – case study

var history = ChatService.chatWithHistory(staffSession, universeId, customerAccount.`type`.get, chatId)

assert(history.id == chatId, "ChatHistory id should be equal customerId") assert(history.messages.size == 5, "Five messages should be created") assert(history.participants.size == 2, "Two participants should be included in chat")

inside (history.messages.head) { case ChatMessage(_type, content, sender, tags, sentAt) => _type should be ("something") sentAt.get should startWith("prefix") tags should contain("one", "two") }

Page 20: Slawek Kluz - Ewolucja modelu danych w testach funkcjonalnych – case study

Wersja 2.0● tests-web

○ możliwość użycia warstwy serwisów do przygotowania danych○ możliwość sprawdzenia stanu danych (eventy)○ asercje z użyciem obiektów modelu

Page 21: Slawek Kluz - Ewolucja modelu danych w testach funkcjonalnych – case study

class DisplayEventTest extends BaseSuite {

behavior of "Events page"

it should "display event with proper data" taggedAs Smoke in { val (operatorEvent, operatorMarket) = EventProvider.createStartFootballMatchWinnerEvent() Backoffice.open().login() val tradingPage = Backoffice.openTradingPage() val eventPage = tradingPage.openEventPage(operatorEvent.id.get) operatorEvent.name shouldBe eventPage.eventName.getText operatorEvent.id.get shouldBe eventPage.eventId.getText operatorEvent.display.get shouldBe eventPage.isEventShow() operatorEvent.active.get shouldBe eventPage.isEventActive() operatorEvent.timeSettings.get.startTime.substring(0,10) shouldBe eventPage.startTime.getText.substring(0,10) }

}

Page 22: Slawek Kluz - Ewolucja modelu danych w testach funkcjonalnych – case study

Wersja 2.0● zalety

○ łatwość wprowadzania zmian/utrzymania kodu○ czytelność kodu○ szybkie testy przeglądarkowe○ tworzenie zewnętrznych narzędzi z użyciem serwisów○ sterowanie mechanizmem serializacji○ wsparcie IDE

● wady○ użycie danych niezgodnych z modelem○ problemy z serializacją

Page 23: Slawek Kluz - Ewolucja modelu danych w testach funkcjonalnych – case study

Pytania