效能測試工具Locust使用指南(二)

weixin_33728268發表於2017-11-27

上一篇文章效能測試工具Locust使用指南(一)主要介紹了Locust的基本概念,主要功能和一個示例,這篇主要講進階的功能.

  • Locust類


一個locustfile至少包含一個繼承了Locust的類.Locust會為被模擬的每個使用者生成locust的例項,這些屬性是應該被實現的:

  • task_set
    task_set屬性應該指向一個TaskSet類, 這個屬性定義了使用者的一些行為,例如執行任務的間隔時間min_waitmax_wait.(如果不定義,則預設1s)

  • weight
    可以在一個檔案裡執行兩個locusts:
    locust -f locust_file.py WebUserLocust MobileUserLocust
    如果希望讓其中一個locust執行得更多,那麼以在這些類上設定一個權重屬性weight 。比如說,WebUserLocust比MobileUserLocust多三倍:

    class WebUserLocust(Locust):
        weight = 3
        ....
    
    class MobileUserLocust(Locust):
        weight = 1
        ....
    
  • host
    如果在locust類中宣告瞭一個host屬性,那麼在命令列中沒有指定主機時將使用它。

  • TaskSet類


每個Locust類必須有一個task_set屬性,task_set指向一個TaskSet類。TaskSet相當於Locust的大腦.
任務設定任務的典型方法是使用任務修飾器:

from locust import Locust, TaskSet, task

class MyTaskSet(TaskSet):
    @task
    def my_task(self):
        print("Locust instance (%r) executing my_task" % (self.locust))

class MyLocust(Locust):
    task_set = MyTaskSet

taskset的一個非常重要的特性是它們可以被巢狀,因為真正的網站通常是以分層的方式構建的,有多個子節。巢狀taskset將允許我們定義一個行為,以更現實的方式模擬使用者。例如,可以用以下結構定義taskset:

class ForumPage(TaskSet):
  @task(20)
  def read_thread(self):
      pass

  @task(1)
  def new_thread(self):
      pass

  @task(5)
  def stop(self):
      self.interrupt()

class UserBehaviour(TaskSet):
  tasks = {ForumPage:10}

  @task
  def index(self):
      pass

在上面的例子中,如果ForumPage在執行UserBehaviour任務集時被選擇執行,那麼ForumPage任務集就會開始執行。ForumPage任務集將選擇它自己的任務之一執行它.

有一個重要的事情需要注意,那就是在ForumPage的stop方法中呼叫self.interrupt()。這實際上是停止執行ForumPage任務集,但UserBehaviour例項將會繼續執行。如果沒有呼叫ForumPage的中斷()方法,那麼Locust一旦啟動就不會停止執行該ForumPage任務。通過使用中斷函式,我們可以結合任務權重定義一個模擬使用者離開測試網站的可能。

還可以使用@ task decorator宣告巢狀的TaskSet,就像宣告普通任務時一樣:

class MyTaskSet(TaskSet):
  @task
  class SubTaskSet(TaskSet):
      @task
      def my_task(self):
          pass
  • 使用Http請求

    • 到目前為止,只討論了Locust使用者的任務排程部分。為了實際載入測試系統,我們需要發出HTTP請求。為了做到這一點,需要使用HttpLocust類。當使用這個類時,每個例項都會得到一個客戶端屬性,它將是HttpSession的一個例項,可用於發出HTTP請求。
      在Locust例項化後建立的HttpSession例項。客戶端支援cookie,因此可以在HTTP請求之間保持會話。

    • URL裡有動態引數的話,可以通過將名稱引數傳遞給HttpSession的不同請求方法來完成。

      #Statistics for these requests will be grouped under: /blog/?id=[id]
      for i in range(10):
          client.get("/blog?id=%i" % i, name="/blog?id=[id]")
      
    • 對共享公共庫的多個locustfile進行分組。在這種情況下,重要的是將project root定義為呼叫locust的目錄,並且建議所有的locustfiles都在project root下的某個地方。
      子目錄定義方法參見下面的例子,但是locust只會匯入於執行的locustfile所處的那個目錄的模組。如果是希望從project root(即執行locust命令的位置)匯入,請確保在匯入任何公共庫之前,在locust檔案中加入sys.path.append(os.getcwd()),這將使project root(即當前工作目錄)是可匯入的。

    • project root

      • init.py
      • common/
        • init.py
        • config.py
        • auth.py
      • locustfiles/
        • init.py
        • web_app.py
        • api.py
        • ecommerce.py

      使用上述專案結構,你的本地化檔案可以使用以下方法匯入公共庫:

      sys.path.append(os.getcwd())
      import common.auth
      

相關文章