본문 바로가기
Today I learned

2020 11 09

by soheemon 2020. 11. 9.

Gatling

scala 파일을 컴파일 후, gatling으로 테스트하기.

짧은 record를 끝내고 이제 내가 생성한 테스트케이스를 실행하려고 했는데...

gatling을 아무리 실행해도 내가 생성한 scala가 목록에 안나왔다.

알고보니.. 컴파일에 실패한 scala파일이 있으면, 목록이 전부 안나오는것 같다.(실패한 파일을 건너 뛰는게아니라 Exception마냥 중단해 버리는듯?)

 

발생하던 에러를 대충 재현해본것- 해당 에러를 잡지 않으면 계속해서 컴파일이 성공했었던 예전 목록만 뜬다..(새로 추가된 scala파일은 안뜸..)

 

그래서 컴파일 에러나는 파일을 삭제해버리고(!) 다시 gatling.bat를 실행하니까 목록이 정상적으로 뜬다..

이 문제의 정석은 에러를 잡는것이지만.. 나는 스칼라를 잘 몰라서...ㅜㅜ

 

Gatling 시나리오 설명

package computerdatabase // 패키지명

import scala.concurrent.duration._

import io.gatling.core.Predef._ // gatling 패키지에서 모듈을 import한다.
import io.gatling.http.Predef._

class BasicSimulation extends Simulation {

  val httpProtocol = http // 모든 Http request에 대한 공통 구성
    .baseUrl("http://computer-database.gatling.io") // 모든 상대 URL 앞에 추가 될 baseUrl
    .acceptHeader("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8") // request 공통헤더
    .doNotTrackHeader("1") 
    .acceptLanguageHeader("en-US,en;q=0.5")
    .acceptEncodingHeader("gzip, deflate")
    .userAgentHeader("Mozilla/5.0 (Windows NT 5.1; rv:31.0) Gecko/20100101 Firefox/31.0")

  val scn = scenario("BasicSimulation") // 시나리오 정의
    .exec(http("request_1") // request명 정의. 보고서에 해당명칭이 표시된다.
      .get("/")) // 이 요청이 GET 메소드로 대상으로 하는 URL
    .pause(5)

  setUp( // 시나리오 START!
    scn.inject(atOnceUsers(1)) // scn이라는 시나리오에 사용자를 한명 주입한다.
  ).protocols(httpProtocol) // 공통 Http request 구성을 사용하도록 한다.
}

프로세스 분리

자아.. 우리가 지금까지 record했던 request들은, 하나의 큰 덩어리였어요.

하지만 테스트를 위해서 selenium의 PageObject 패턴과 유사한 비즈니스 프로세스로 분할할 필요가 있어요. 왜냐 기능별로 분할해 두면 유지보수가 원활하고, 코드를 재사용 가능하고, 보다 더 세밀한 테스트를 구성할 수가 있으니까요!

 

한가지 예를 들어볼게요

/*
 * Copyright 2011-2020 GatlingCorp (https://gatling.io)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package computerdatabase.advanced

import scala.concurrent.duration._

import io.gatling.core.Predef._
import io.gatling.http.Predef._

class AdvancedSimulationStep01 extends Simulation {

  // Let's split this big scenario into composable business processes, like one would do with PageObject pattern with Selenium

  // object are native Scala singletons
  object Search {

    val search = exec(
      http("Home") // 레포트에서 보이는 명칭.
        .get("/")
    ).pause(1)
      .exec(
        http("Search")
          .get("/computers?f=macbook")
      )
      .pause(1)
      .exec(
        http("Select")
          .get("/computers/6")
      )
      .pause(1)
  }

  object Browse {

    val browse = exec(
      http("Home")
        .get("/")
    ).pause(2)
      .exec(
        http("Page 1")
          .get("/computers?p=1")
      )
      .pause(670 milliseconds)
      .exec(
        http("Page 2")
          .get("/computers?p=2")
      )
      .pause(629 milliseconds)
      .exec(
        http("Page 3")
          .get("/computers?p=3")
      )
      .pause(734 milliseconds)
      .exec(
        http("Page 4")
          .get("/computers?p=4")
      )
      .pause(5)
  }

  object Edit {

    val edit = exec(
      http("Form")
        .get("/computers/new")
    ).pause(1)
      .exec(
        http("Post")
          .post("/computers")
          .formParam("name", "Beautiful Computer")
          .formParam("introduced", "2012-05-30")
          .formParam("discontinued", "")
          .formParam("company", "37")
      )
  }

  val httpProtocol = http
    .baseUrl("http://computer-database.gatling.io")
    .acceptHeader("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
    .doNotTrackHeader("1")
    .acceptLanguageHeader("en-US,en;q=0.5")
    .acceptEncodingHeader("gzip, deflate")
    .userAgentHeader("Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:16.0) Gecko/20100101 Firefox/16.0")

  // Now, we can write the scenario as a composition
  val scn = scenario("Scenario Name").exec(Search.search, Browse.browse, Edit.edit)	//차례로 실행이 가능하다.

  setUp(scn.inject(atOnceUsers(1)).protocols(httpProtocol))	//생성한 시나리오를 기반으로 유저는 1생성해서 시나리오 실행.
}

record를 그대로 가져다 실행하는것은 코드 유지보수하기가 어렵다. 모듈화하면 아래와 같이 실행하기에도 편리할것 같다.

// 적절하게 모듈화를 진행해 줬다면 아래와 같이 시나리오 생성이 가능하다.
val users = scenario("Users").exec(Search.search, Browse.browse)
val admins = scenario("Admin").exec(Search.search, Browse.browse, Edit.edit);

setUp(users.injext(atOnceUsers(10)).protocols(httpProtocol))	//10명 생성해서 테스트 가능..

'Today I learned' 카테고리의 다른 글

2020 11 19  (0) 2020.11.19
2020 11 11  (0) 2020.11.11
2020 11 06  (0) 2020.11.06
2020 11 05  (0) 2020.11.05
2020 11 03  (0) 2020.11.03

댓글