1. 程式人生 > 其它 >pytest入門

pytest入門

簡介

The pytest framework makes it easy to write small, readable tests, and can scale to support complex functional testing for applications and libraries.

pytest是一個成熟的python測試框架,易於編寫,小巧易讀,擴充套件性高。

  • 安裝:python -m pip install pytest(需要python 3.7+)

規範

在pytest測試框架中,需要遵循以下規範:

  • 測試檔名要符合test_*.py*_test.py
    • 如果團隊內之前沒用過pytest,建議固定使用其中一個
    • 示例:test_login.py
  • 測試類要以Test開頭,且不能帶有__init__()方法
    • 示例:class TestLogin:
  • 在單個測試類中,可以有多個測試函式。測試函式名符合test_*

示例程式碼1

  • 編寫test_sample.py
def inc(x):
    # 入參值加1
    return x + 1

def test_inc_1():
    # 斷言
    assert inc(3) == 4

def test_inc_2():
    # 斷言
    assert inc(3) == 5
  • 在程式碼所在目錄下執行命令:python -m pytest

示例程式碼2

  • 編寫test_sample.py
import pytest

def test_001():
    print("test_001")

def test_002():
    print("test_002")

if __name__ == '__main__':
    # 使用pytest.main()可以傳入可執行引數,通過[]進行分割,[]內多個引數使用半形逗號分割
    pytest.main(["-v", "test_sample.py"])
  • 在程式碼所在目錄下執行命令:python test_sample.py

示例程式碼3-生成html格式的測試報告

  • 編寫test_sample.py
import pytest

def inc(x):
    return x + 1

def test_inc_1():
    # 斷言成功
    assert inc(3) == 4

def test_inc_2():
    # 斷言失敗
    assert inc(3) == 5

users = ["zhaoda", "qianer", "sunsan", "lisi"]
def test_userin():
    # 斷言失敗
    assert "zhouwu" in users

if __name__ == '__main__':
    # 測試test_sample.py檔案,並生成html格式的測試報告
    # 需要使用pip安裝pytest-html
    pytest.main(["--html=./report.html", "test_sample.py"])
  • 在程式碼所在目錄下執行命令:python test_sample.py
  • 可以通過瀏覽器開啟生成的html檔案

示例程式碼4-介面測試

  • 先用go語言寫了一個簡單的介面,傳參userId,返回username等使用者資訊。
package main

import (
	"context"
	"log"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"
	"github.com/gin-gonic/gin"
)

type ReqUserInfo struct {
	UserId int `json:userId`
}

func f2(c *gin.Context) {
	// 解析請求體
	var req ReqUserInfo
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"ERROR": err.Error(),
		})
		return
	}

	var rsp struct {
		UserId   int    `json:"userId"`
		Username string `json:"username"`
		UserSex  int    `json:"userSex"`
	}

	rsp.UserId = req.UserId
	rsp.Username = "zhangsan"
	rsp.UserSex = 0

	c.JSON(http.StatusOK, rsp)
}

func main() {
	// gin.SetMode(gin.ReleaseMode)

	r := gin.Default()
	r.GET("/user", f2)

	// 設定程式優雅退出
	srv := &http.Server{
		Addr:    "127.0.0.1:8000",
		Handler: r,
	}

	go func() {
		if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			log.Fatalf("listen failed, %v\n", err)
		}
	}()

	quit := make(chan os.Signal, 1)
	signal.Notify(quit, os.Interrupt, syscall.SIGTERM, syscall.SIGINT)
	<-quit
	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
	defer cancel()

	if err := srv.Shutdown(ctx); err != nil {
		log.Fatalf("server shutdown failed, err: %v\n", err)
	}
	select {
	case <-ctx.Done():
		log.Println("timeout of 1 seconds")
	}
	log.Println("server shutdown")
}
  • 執行服務端:go run main.go
  • 編寫測試程式碼:test_user.py
import pytest
import requests
import json

def test_user():
    url = "http://127.0.0.1:8000/user"
    headers = {
        "Content-Type": "application/json"
    }
    data = {
        "userId": 123456,
    }
    req = requests.get(url=url, headers=headers, data=json.dumps(data))
    print(req.text)
    assert req.json()["username"] == "zhangsan"

if __name__ == '__main__':
    pytest.main(["-v", "-s","test_user.py"])
  • 執行測試:python test_user.py

參考