SlideShare una empresa de Scribd logo
1 de 23
Descargar para leer sin conexión
Ewolucja modelu danych
w testach funkcjonalnych -
case study
Sławomir Kluz
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
Testy
● API: spójność danych, szybki feedback, wpływ na integracje + CD
● website/backoffice - selenium
● testy wydajnościwe API
Wersja 1.0
● start projektu - testy API
● gatling jako framework testowy (testy funkcjonalne + wydajnościowe)
● model danych
○ tekst/mapy
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}"
}"""
}
Wersja 1.0
● start projektu - testy API
● gatling jako framework testowy (testy funkcjonalne + wydajnościowe)
● model danych
○ tekst/mapy
○ json wrapper
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
}
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)
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
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
Wersja 2.0
● struktura kodu projektu - sbt
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
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)
object PaymentMethodSampler {
def creditCardPayment = PaymentMethod(
provider = Some("realex"),
`type` = Some("credit-card")
)
def invalidProviderPayment = PaymentMethod(
provider = Some("polcard"),
`type` = Some("credit-card")
)
Wersja 2.0
● tests-api
○ serializacja/deserializacja obiektów modelu
○ wbudowany mechanizm z rest-assured
○ warstwa “serwisów”
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)
}
}
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])
}
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")
}
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
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)
}
}
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ą
Pytania

Más contenido relacionado

Destacado

Tarea1 modulo 1
Tarea1 modulo 1Tarea1 modulo 1
Tarea1 modulo 1yasminpri
 
Micro station BIOFRANCE : Résultats des tests selon protocole VEOLIA en condi...
Micro station BIOFRANCE : Résultats des tests selon protocole VEOLIA en condi...Micro station BIOFRANCE : Résultats des tests selon protocole VEOLIA en condi...
Micro station BIOFRANCE : Résultats des tests selon protocole VEOLIA en condi...idealconnaissances
 
Suivi Mares - 2015 - PCN
Suivi Mares - 2015 - PCN Suivi Mares - 2015 - PCN
Suivi Mares - 2015 - PCN LISEA
 
Vpitois competence production_du_smpbr
Vpitois competence production_du_smpbrVpitois competence production_du_smpbr
Vpitois competence production_du_smpbridealconnaissances
 
Bmouline evolutions reglementaires_anc
Bmouline evolutions reglementaires_ancBmouline evolutions reglementaires_anc
Bmouline evolutions reglementaires_ancidealconnaissances
 
Automating with CloudFormation
Automating with CloudFormationAutomating with CloudFormation
Automating with CloudFormationWee Keat Chin
 
La LGV et ses effets dans le champ du tourisme
La LGV et ses effets dans le champ du tourismeLa LGV et ses effets dans le champ du tourisme
La LGV et ses effets dans le champ du tourismeLISEA
 

Destacado (9)

Tarea1 modulo 1
Tarea1 modulo 1Tarea1 modulo 1
Tarea1 modulo 1
 
Fall Home Prep
Fall Home PrepFall Home Prep
Fall Home Prep
 
Micro station BIOFRANCE : Résultats des tests selon protocole VEOLIA en condi...
Micro station BIOFRANCE : Résultats des tests selon protocole VEOLIA en condi...Micro station BIOFRANCE : Résultats des tests selon protocole VEOLIA en condi...
Micro station BIOFRANCE : Résultats des tests selon protocole VEOLIA en condi...
 
Suivi Mares - 2015 - PCN
Suivi Mares - 2015 - PCN Suivi Mares - 2015 - PCN
Suivi Mares - 2015 - PCN
 
Vpitois competence production_du_smpbr
Vpitois competence production_du_smpbrVpitois competence production_du_smpbr
Vpitois competence production_du_smpbr
 
Bmouline evolutions reglementaires_anc
Bmouline evolutions reglementaires_ancBmouline evolutions reglementaires_anc
Bmouline evolutions reglementaires_anc
 
Automating with CloudFormation
Automating with CloudFormationAutomating with CloudFormation
Automating with CloudFormation
 
Diabetes Quiz
Diabetes QuizDiabetes Quiz
Diabetes Quiz
 
La LGV et ses effets dans le champ du tourisme
La LGV et ses effets dans le champ du tourismeLa LGV et ses effets dans le champ du tourisme
La LGV et ses effets dans le champ du tourisme
 

Similar a Slawek Kluz - Ewolucja modelu danych w testach funkcjonalnych – case study

CQRS, ES, Scala @ Confitura 2012
CQRS, ES, Scala @ Confitura 2012CQRS, ES, Scala @ Confitura 2012
CQRS, ES, Scala @ Confitura 2012Maciek Próchniak
 
NK API - Przykłady
NK API - PrzykładyNK API - Przykłady
NK API - Przykładynasza-klasa
 
[PL] Jak programować aby nie zwariować
[PL] Jak programować aby nie zwariować[PL] Jak programować aby nie zwariować
[PL] Jak programować aby nie zwariowaćJakub Marchwicki
 
Patronage 2016 Windows 10 Warsztaty
Patronage 2016 Windows 10 WarsztatyPatronage 2016 Windows 10 Warsztaty
Patronage 2016 Windows 10 Warsztatyintive
 
Metaprogramowanie w JS
Metaprogramowanie w JSMetaprogramowanie w JS
Metaprogramowanie w JSDawid Rusnak
 
Aplikacje internetowe (2010)
Aplikacje internetowe (2010)Aplikacje internetowe (2010)
Aplikacje internetowe (2010)Adrian Kalbarczyk
 
Testowanie bezpieczeństwa aplikacji dedykowanych na platformę Android
Testowanie bezpieczeństwa aplikacji dedykowanych na platformę AndroidTestowanie bezpieczeństwa aplikacji dedykowanych na platformę Android
Testowanie bezpieczeństwa aplikacji dedykowanych na platformę AndroidSecuRing
 
tRPC - czy to koniec GraphQL?
tRPC - czy to koniec GraphQL?tRPC - czy to koniec GraphQL?
tRPC - czy to koniec GraphQL?Brainhub
 
Confitura 2018 - Sekretne życie jobów Sparkowych
Confitura 2018 - Sekretne życie jobów SparkowychConfitura 2018 - Sekretne życie jobów Sparkowych
Confitura 2018 - Sekretne życie jobów SparkowychMarcin Jasiński
 
4Developers 2015: Property-based testing w języku Scala - Paweł Grajewski
4Developers 2015: Property-based testing w języku Scala - Paweł Grajewski4Developers 2015: Property-based testing w języku Scala - Paweł Grajewski
4Developers 2015: Property-based testing w języku Scala - Paweł GrajewskiPROIDEA
 
Nowe Trendy W Projektowaniu Aplikacji Webowych
Nowe Trendy W Projektowaniu Aplikacji WebowychNowe Trendy W Projektowaniu Aplikacji Webowych
Nowe Trendy W Projektowaniu Aplikacji WebowychMarcin Daczkowski
 
20181004 Hubert Kobierzewski - Jakość danych w organizacji
20181004 Hubert Kobierzewski - Jakość danych w organizacji20181004 Hubert Kobierzewski - Jakość danych w organizacji
20181004 Hubert Kobierzewski - Jakość danych w organizacjiHubert Kobierzewski
 
StreamInsight - Analiza danych w ruchu
StreamInsight - Analiza danych w ruchuStreamInsight - Analiza danych w ruchu
StreamInsight - Analiza danych w ruchuWlodek Bielski
 
Elitmind @ SQLDay2018: Stream Analytics i Machine Learning – czy to dobrze do...
Elitmind @ SQLDay2018: Stream Analytics i Machine Learning – czy to dobrze do...Elitmind @ SQLDay2018: Stream Analytics i Machine Learning – czy to dobrze do...
Elitmind @ SQLDay2018: Stream Analytics i Machine Learning – czy to dobrze do...Elitmind
 
Mts 2013 tomasz kopacz - windows 8, office 365, workflow manager, windows a...
Mts 2013   tomasz kopacz - windows 8, office 365, workflow manager, windows a...Mts 2013   tomasz kopacz - windows 8, office 365, workflow manager, windows a...
Mts 2013 tomasz kopacz - windows 8, office 365, workflow manager, windows a...Tomasz Kopacz
 
Wprowadzenie do języka Swift, czyli nowe podejście do programowania aplikacji...
Wprowadzenie do języka Swift, czyli nowe podejście do programowania aplikacji...Wprowadzenie do języka Swift, czyli nowe podejście do programowania aplikacji...
Wprowadzenie do języka Swift, czyli nowe podejście do programowania aplikacji...The Software House
 

Similar a Slawek Kluz - Ewolucja modelu danych w testach funkcjonalnych – case study (20)

O danych w 2016
O danych w 2016O danych w 2016
O danych w 2016
 
WarszawQA_#9
WarszawQA_#9WarszawQA_#9
WarszawQA_#9
 
CQRS, ES, Scala @ Confitura 2012
CQRS, ES, Scala @ Confitura 2012CQRS, ES, Scala @ Confitura 2012
CQRS, ES, Scala @ Confitura 2012
 
NK API - Przykłady
NK API - PrzykładyNK API - Przykłady
NK API - Przykłady
 
[PL] Jak programować aby nie zwariować
[PL] Jak programować aby nie zwariować[PL] Jak programować aby nie zwariować
[PL] Jak programować aby nie zwariować
 
Patronage 2016 Windows 10 Warsztaty
Patronage 2016 Windows 10 WarsztatyPatronage 2016 Windows 10 Warsztaty
Patronage 2016 Windows 10 Warsztaty
 
Zwinny_Analityk_SIW_Panel
Zwinny_Analityk_SIW_PanelZwinny_Analityk_SIW_Panel
Zwinny_Analityk_SIW_Panel
 
Metaprogramowanie w JS
Metaprogramowanie w JSMetaprogramowanie w JS
Metaprogramowanie w JS
 
Aplikacje internetowe (2010)
Aplikacje internetowe (2010)Aplikacje internetowe (2010)
Aplikacje internetowe (2010)
 
Testowanie bezpieczeństwa aplikacji dedykowanych na platformę Android
Testowanie bezpieczeństwa aplikacji dedykowanych na platformę AndroidTestowanie bezpieczeństwa aplikacji dedykowanych na platformę Android
Testowanie bezpieczeństwa aplikacji dedykowanych na platformę Android
 
tRPC - czy to koniec GraphQL?
tRPC - czy to koniec GraphQL?tRPC - czy to koniec GraphQL?
tRPC - czy to koniec GraphQL?
 
Confitura 2018 - Sekretne życie jobów Sparkowych
Confitura 2018 - Sekretne życie jobów SparkowychConfitura 2018 - Sekretne życie jobów Sparkowych
Confitura 2018 - Sekretne życie jobów Sparkowych
 
4Developers 2015: Property-based testing w języku Scala - Paweł Grajewski
4Developers 2015: Property-based testing w języku Scala - Paweł Grajewski4Developers 2015: Property-based testing w języku Scala - Paweł Grajewski
4Developers 2015: Property-based testing w języku Scala - Paweł Grajewski
 
Android i REST
Android i RESTAndroid i REST
Android i REST
 
Nowe Trendy W Projektowaniu Aplikacji Webowych
Nowe Trendy W Projektowaniu Aplikacji WebowychNowe Trendy W Projektowaniu Aplikacji Webowych
Nowe Trendy W Projektowaniu Aplikacji Webowych
 
20181004 Hubert Kobierzewski - Jakość danych w organizacji
20181004 Hubert Kobierzewski - Jakość danych w organizacji20181004 Hubert Kobierzewski - Jakość danych w organizacji
20181004 Hubert Kobierzewski - Jakość danych w organizacji
 
StreamInsight - Analiza danych w ruchu
StreamInsight - Analiza danych w ruchuStreamInsight - Analiza danych w ruchu
StreamInsight - Analiza danych w ruchu
 
Elitmind @ SQLDay2018: Stream Analytics i Machine Learning – czy to dobrze do...
Elitmind @ SQLDay2018: Stream Analytics i Machine Learning – czy to dobrze do...Elitmind @ SQLDay2018: Stream Analytics i Machine Learning – czy to dobrze do...
Elitmind @ SQLDay2018: Stream Analytics i Machine Learning – czy to dobrze do...
 
Mts 2013 tomasz kopacz - windows 8, office 365, workflow manager, windows a...
Mts 2013   tomasz kopacz - windows 8, office 365, workflow manager, windows a...Mts 2013   tomasz kopacz - windows 8, office 365, workflow manager, windows a...
Mts 2013 tomasz kopacz - windows 8, office 365, workflow manager, windows a...
 
Wprowadzenie do języka Swift, czyli nowe podejście do programowania aplikacji...
Wprowadzenie do języka Swift, czyli nowe podejście do programowania aplikacji...Wprowadzenie do języka Swift, czyli nowe podejście do programowania aplikacji...
Wprowadzenie do języka Swift, czyli nowe podejście do programowania aplikacji...
 

Más de kraqa

RestAssured w sluzbie testow API
RestAssured w sluzbie testow APIRestAssured w sluzbie testow API
RestAssured w sluzbie testow APIkraqa
 
Postman - podstawy testowania REST API
Postman - podstawy testowania REST APIPostman - podstawy testowania REST API
Postman - podstawy testowania REST APIkraqa
 
Stanislaw potoczny kra_qa_21.01.20
Stanislaw potoczny kra_qa_21.01.20Stanislaw potoczny kra_qa_21.01.20
Stanislaw potoczny kra_qa_21.01.20kraqa
 
Machine learning powered regression - KraQA 42 - Pawel Dyrek
Machine learning powered regression - KraQA 42 - Pawel Dyrek Machine learning powered regression - KraQA 42 - Pawel Dyrek
Machine learning powered regression - KraQA 42 - Pawel Dyrek kraqa
 
Kontrakt testy - KraQA 42 - Slawomir Radzyminski
Kontrakt testy - KraQA 42 - Slawomir RadzyminskiKontrakt testy - KraQA 42 - Slawomir Radzyminski
Kontrakt testy - KraQA 42 - Slawomir Radzyminskikraqa
 
KraQA#41 - PageFactory
KraQA#41 - PageFactoryKraQA#41 - PageFactory
KraQA#41 - PageFactorykraqa
 
KraQA#39 - Jak testowac tool do testow
KraQA#39 - Jak testowac tool do testowKraQA#39 - Jak testowac tool do testow
KraQA#39 - Jak testowac tool do testowkraqa
 
Hyperion - wystarczy jeden shake
Hyperion - wystarczy jeden shakeHyperion - wystarczy jeden shake
Hyperion - wystarczy jeden shakekraqa
 
Wybor urzadzen mobilnych do testow
Wybor urzadzen mobilnych do testowWybor urzadzen mobilnych do testow
Wybor urzadzen mobilnych do testowkraqa
 
Continuous security
Continuous securityContinuous security
Continuous securitykraqa
 
Let s meet inside
Let s meet insideLet s meet inside
Let s meet insidekraqa
 
O wezu przy kawie
O wezu przy kawieO wezu przy kawie
O wezu przy kawiekraqa
 
Strategia do automatów
Strategia do automatówStrategia do automatów
Strategia do automatówkraqa
 
Z czym do api
Z czym do apiZ czym do api
Z czym do apikraqa
 
Jenkins pipelines
Jenkins pipelinesJenkins pipelines
Jenkins pipelineskraqa
 
Testy UI
Testy UITesty UI
Testy UIkraqa
 
Tester w pułapce myślenia
Tester w pułapce myśleniaTester w pułapce myślenia
Tester w pułapce myśleniakraqa
 
Kiedy tester zostaje managerem
Kiedy tester zostaje manageremKiedy tester zostaje managerem
Kiedy tester zostaje manageremkraqa
 
KraQA#32 - RODO
KraQA#32 - RODOKraQA#32 - RODO
KraQA#32 - RODOkraqa
 
SkładQA 2018 - Daniel Dec
SkładQA 2018 - Daniel DecSkładQA 2018 - Daniel Dec
SkładQA 2018 - Daniel Deckraqa
 

Más de kraqa (20)

RestAssured w sluzbie testow API
RestAssured w sluzbie testow APIRestAssured w sluzbie testow API
RestAssured w sluzbie testow API
 
Postman - podstawy testowania REST API
Postman - podstawy testowania REST APIPostman - podstawy testowania REST API
Postman - podstawy testowania REST API
 
Stanislaw potoczny kra_qa_21.01.20
Stanislaw potoczny kra_qa_21.01.20Stanislaw potoczny kra_qa_21.01.20
Stanislaw potoczny kra_qa_21.01.20
 
Machine learning powered regression - KraQA 42 - Pawel Dyrek
Machine learning powered regression - KraQA 42 - Pawel Dyrek Machine learning powered regression - KraQA 42 - Pawel Dyrek
Machine learning powered regression - KraQA 42 - Pawel Dyrek
 
Kontrakt testy - KraQA 42 - Slawomir Radzyminski
Kontrakt testy - KraQA 42 - Slawomir RadzyminskiKontrakt testy - KraQA 42 - Slawomir Radzyminski
Kontrakt testy - KraQA 42 - Slawomir Radzyminski
 
KraQA#41 - PageFactory
KraQA#41 - PageFactoryKraQA#41 - PageFactory
KraQA#41 - PageFactory
 
KraQA#39 - Jak testowac tool do testow
KraQA#39 - Jak testowac tool do testowKraQA#39 - Jak testowac tool do testow
KraQA#39 - Jak testowac tool do testow
 
Hyperion - wystarczy jeden shake
Hyperion - wystarczy jeden shakeHyperion - wystarczy jeden shake
Hyperion - wystarczy jeden shake
 
Wybor urzadzen mobilnych do testow
Wybor urzadzen mobilnych do testowWybor urzadzen mobilnych do testow
Wybor urzadzen mobilnych do testow
 
Continuous security
Continuous securityContinuous security
Continuous security
 
Let s meet inside
Let s meet insideLet s meet inside
Let s meet inside
 
O wezu przy kawie
O wezu przy kawieO wezu przy kawie
O wezu przy kawie
 
Strategia do automatów
Strategia do automatówStrategia do automatów
Strategia do automatów
 
Z czym do api
Z czym do apiZ czym do api
Z czym do api
 
Jenkins pipelines
Jenkins pipelinesJenkins pipelines
Jenkins pipelines
 
Testy UI
Testy UITesty UI
Testy UI
 
Tester w pułapce myślenia
Tester w pułapce myśleniaTester w pułapce myślenia
Tester w pułapce myślenia
 
Kiedy tester zostaje managerem
Kiedy tester zostaje manageremKiedy tester zostaje managerem
Kiedy tester zostaje managerem
 
KraQA#32 - RODO
KraQA#32 - RODOKraQA#32 - RODO
KraQA#32 - RODO
 
SkładQA 2018 - Daniel Dec
SkładQA 2018 - Daniel DecSkładQA 2018 - Daniel Dec
SkładQA 2018 - Daniel Dec
 

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

  • 1. Ewolucja modelu danych w testach funkcjonalnych - case study Sławomir Kluz
  • 2. 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
  • 3. Testy ● API: spójność danych, szybki feedback, wpływ na integracje + CD ● website/backoffice - selenium ● testy wydajnościwe API
  • 4. Wersja 1.0 ● start projektu - testy API ● gatling jako framework testowy (testy funkcjonalne + wydajnościowe) ● model danych ○ tekst/mapy
  • 5. 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}" }""" }
  • 6. Wersja 1.0 ● start projektu - testy API ● gatling jako framework testowy (testy funkcjonalne + wydajnościowe) ● model danych ○ tekst/mapy ○ json wrapper
  • 7. 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 }
  • 8. 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)
  • 9. 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
  • 10. 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
  • 11. Wersja 2.0 ● struktura kodu projektu - sbt
  • 12.
  • 13. 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
  • 14. 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)
  • 15. object PaymentMethodSampler { def creditCardPayment = PaymentMethod( provider = Some("realex"), `type` = Some("credit-card") ) def invalidProviderPayment = PaymentMethod( provider = Some("polcard"), `type` = Some("credit-card") )
  • 16. Wersja 2.0 ● tests-api ○ serializacja/deserializacja obiektów modelu ○ wbudowany mechanizm z rest-assured ○ warstwa “serwisów”
  • 17. 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) } }
  • 18. 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]) }
  • 19. 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") }
  • 20. 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
  • 21. 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) } }
  • 22. 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ą