パンダとExcelはPytestデータドライブを実装しています

前書き

以前に共有されたツイートの自動テストは 必須です-データ駆動型DDT  は、データ駆動型を実現するために、unittestフレームワークにJSONファイルとYAMLファイルの操作を導入しました。では、pytestでは、どのように実装する必要がありますか?

 

PytestはJSON / YAMLファイルを操作して、データ駆動型を実現します

まず、データ駆動型にpytestを使用するという基本的な考え方に従って、JSONファイルとYAMLファイルを読み取るメソッドを作成します:

def test_read_data_from_json_yaml(data_file):

    return_value = []

    data_file_path = os.path.abspath(data_file)

    print(data_file_path)

    _is_yaml_file = data_file_path.endswith((".yml", ".yaml"))

    with codecs.open(data_file_path, 'r', 'utf-8') as f:

        #从YAML或JSON文件中加载数据

        if _is_yaml_file:

            data = yaml.safe_load(f)

        else:

            data = json.load(f)

    for i, elem in enumerate(data):

        if isinstance(data, dict):

            key, value = elem, data[elem]

            if isinstance(value, dict):

                case_data = []

                for v in value.values():

                    case_data.append(v)

                return_value.append(tuple(case_data))

            else:

                return_value.append((value,))

    return return_value

関数test_read_data_from_json_yamlは、JSONファイルとYAMLファイルの自動読み取りを実現し、JSONファイルとYAMLファイルのデータを抽出して、pytest.mark.parametrizeが受信できる方法でそれらを返します。

 

この関数メソッドを使用すると、JSONまたはYAMLファイルのデータをpytest.mark.parametrizeで認識される形式に変換し、このメソッドを介して直接渡すことができます。

 

それを練習して、APITestプロジェクトのルートディレクトリに次のファイルディレクトリを作成しましょう。

|--APITest

    |--tests_pytest_ddt

        |--test_baidu_ddt.py

        |--test_baidu_ddt.json

        |--test_baidu_ddt.yaml

        |--test_baidu_ddt.xlsx

        |--__init__.py

        |--conftest.py

その中で、test_baidu_ddt.jsonファイルの内容は次のとおりです。

{ 

  "case1": {

  "search_string": "testing",

  "expect_string": "Testing"

  },

  "case2": {

  "search_string": "hello_world.com",

  "expect_string": "Testing"

  }

}

test_baidu_ddt.yamlファイルの内容は次のとおりです。

"case1":

  "search_string": "testing"

  "expect_string": "Testing"

"case2": 

  "search_string": "hello_world.com"

  "expect_string": "Testing"

test_baidu_ddt.pyファイルのコードは次のとおりです。

import codecs
import json
import os
import time
import pytest
import yaml


def test_read_data_from_json_yaml(data_file):

    return_value = []

    data_file_path = os.path.abspath(data_file)

    print(data_file_path)

    _is_yaml_file = data_file_path.endswith((".yml", ".yaml"))

    with codecs.open(data_file_path, 'r', 'utf-8') as f:

        #从YAML或JSON文件中加载数据

        if _is_yaml_file:

            data = yaml.safe_load(f)

        else:

            data = json.load(f)

    for i, elem in enumerate(data):

        if isinstance(data, dict):

            key, value = elem, data[elem]

            if isinstance(value, dict):

                case_data = []

                for v in value.values():

                    case_data.append(v)

                return_value.append(tuple(case_data))

            else:

                return_value.append((value,))

    return return_value


@pytest.mark.baidu
class TestBaidu:

    @pytest.mark.parametrize('search_string, expect_string',  test_read_data_from_json_yaml('tests_pytest_ddt/test_baidu_ddt.yaml'))

    def test_baidu_search(self, login, search_string, expect_string):

        driver, s, base_url = login

        driver.get(base_url + "/")

        driver.find_element_by_id("kw").send_keys(search_string)

        driver.find_element_by_id("su").click()

        time.sleep(2)

        search_results = driver.find_element_by_xpath('//*[@id="1"]/h3/a').get_attribute('innerHTML')

        print(search_results)

        assert (expect_string in search_results) is True



if __name__ == "__main__":

    pytest.main(['-s', '-v'])

このファイル のコードは、Pytestテストフレームワークで説明されているコード(データドライブ)と ほぼ同じです。唯一の変更点は、新しいメソッドtest_read_data_from_json_yamlが追加されたことです。さらに、@ pytest.mark.parametrizeのパラメーターがから変更されました。ファイルに直接パラメーターを提供します。パラメーターを提供します。

(test_read_data_from_json_yaml('tests_pytest_ddt/test_baidu_ddt.yaml'))

 

次のようにコマンドラインで実行します。

D:\Python_Test\APITest>pytest tests_pytest_ddt -s -v

 

実行後の結果は次のとおりです
画像。
両方のテストケースが実行され、YAMLファイルのデータが正しく読み取られていることがわかります。

では、JSONファイルのデータを今すぐ実行したい場合はどうでしょうか。上記のコードで渡されたyamlファイルのサフィックスをjsonファイルのサフィックスに置き換えて再実行してください。

 

PytestはExcelファイルを操作してデータドライブを実現します

実際のアプリケーションでは、多くの企業がデータの駆動にExcelも使用しています。Pythonには、Excelを読み書きするための多くのライブラリがあり、一般的なライブラリはxlrd、xlwt、およびopenpyxlです。xlrdとxlwtは、それぞれ読み取りと書き込みにのみ使用でき、同じ読み取り操作と書き込み操作を実現できるため、コード行数が多くなり、徐々に人気が低下しています。したがって、以下ではopenpyxlの使用に焦点を当てます。

 

openpyxlのインストール

pip install openpyxl

 

openpyxlの使用

from openpyxl import load_workbook, Workbook

if __name__ == "__main__":
    # 创建一个workbook
    file_name = r'c:\test.xlsx'
    wb = Workbook()

    # 创建一个sheet,名为Testing,把它插入到最前的位置
    wb.create_sheet('Testing',0)

    # 创建一个sheet,名为TEST,把它插入index为1的位置
    wb.create_sheet('TEST',1)

    # 保存表格
    wb.save(file_name)
    
    # 读和写
    # 初始化表格
    wb2 = load_workbook(file_name)

    # 读,获取所有的sheet名称
    print(wb2.sheetnames)


    # 获取sheet名为Testing的表格
    s = wb2['Testing']

    # 将A1行的值设置为Testing
    s['A1'] = 'Testing'

    # 将第2行,第一列的值设置为1
    s.cell(row=2, column=1).value = 1

    # 打印第2行第一列单元格的值 --方法1
    print(s.cell(row=2,column=1).value)

    # 打印第2行第一列单元格的值 --方法2
    print(s['A2'].value)

    # 保存表格
    wb.save(file_name)

上記のコードブロックに示されているように、openpyxlの使用法を簡単に紹介します。これには、テーブルの作成、シート名の作成、セルの値の読み取り、セルの値の設定などが含まれます。openpyxlを使用してExcelを操作するのは比較的簡単であることがわかります。

 

openpyxlをpytestと組み合わせて、データ駆動型を実現

ファイルtest_baidu_ddt.xlsxの内容は次のとおりです(シート名Testing):
画像
Excelを読み取るメソッドを記述しましょう。コードは次のとおりです。

def test_read_data_from_excel(excel_file, sheet_name):

    return_value = []

    # 判断文件是否存在
    if not os.path.exists(excel_file):
        raise ValueError("File not exists")

    # 打开指定的sheet
    wb = load_workbook(excel_file)

    # 按照pytest接受的格式输出数据
    for s in wb.sheetnames:
        if s == sheet_name:
            sheet = wb[sheet_name]
            for row in sheet.rows:
                return_value.append([col.value for col in row])

    # 第一行数据是标题,故skip掉
    return return_value[1:]

test_baidu_ddt.pyファイルを更新し、test_read_data_from_excelメソッドを追加します。更新されたコードは次のとおりです。

import codecs
import json
import os
import time
import pytest
import yaml
from openpyxl import load_workbook


def test_read_data_from_json_yaml(data_file):
    return_value = []
    data_file_path = os.path.abspath(data_file)
    print(data_file_path)

    _is_yaml_file = data_file_path.endswith((".yml", ".yaml"))
    with codecs.open(data_file_path, 'r', 'utf-8') as f:
        # 从YAML或JSON文件中加载数据
        if _is_yaml_file:
            data = yaml.safe_load(f)
        else:
            data = json.load(f)

    for i, elem in enumerate(data):
        if isinstance(data, dict):
            key, value = elem, data[elem]
            if isinstance(value, dict):
                case_data = []
                for v in value.values():
                    case_data.append(v)
                return_value.append(tuple(case_data))
            else:
                return_value.append((value,))
    return return_value


def test_read_data_from_excel(excel_file, sheet_name):

    return_value = []
    if not os.path.exists(excel_file):
        raise ValueError("File not exists")

    wb = load_workbook(excel_file)
    for s in wb.sheetnames:
        if s == sheet_name:
            sheet = wb[sheet_name]
            for row in sheet.rows:
                return_value.append([col.value for col in row])
    print(return_value)
    return return_value[1:]


@pytest.mark.baidu
class TestBaidu:
    # 注意,此处调用我换成了读Excel的方法

    @pytest.mark.parametrize('search_string, expect_string',  test_read_data_from_excel(r'D\Python_Test\APITest\tests_pytest_ddt\test_baidu_ddt.xlsx', 'Testing'))

    def test_baidu_search(self, login, search_string, expect_string):
        driver, s, base_url = login
        driver.get(base_url + "/")
        driver.find_element_by_id("kw").send_keys(search_string)
        driver.find_element_by_id("su").click()
        time.sleep(2)

        search_results = driver.find_element_by_xpath('//*[@id="1"]/h3/a').get_attribute('innerHTML')
        print(search_results)
        assert (expect_string in search_results) is True


if __name__ == "__main__":
    pytest.main(['-s', '-v','tests_pytest_ddt'])

次のように、コマンドラインで再度実行します。

D:\Python_Test\APITest>pytest tests_pytest_ddt -s -v

実行後に結果を確認すると、テストが正しく実行され、Excelで指定されたシート名からテストデータが取得されていることがわかります。

 

 

パンダはデータ駆動型です

OpenpyxlはExcelを非常に簡潔に操作しますが、Pandasと比較すると、十分に簡潔ではなく、openpyxlはPandasほど効率的ではありません。特に、テーブルの項目が多すぎる場合、openpyxlは遅くなります。

Pandasは、構造化データを分析するための強力なツールセットです。Numpy(高性能マトリックス操作を提供)に基づいています。Pandasは、データマイニングとデータ分析に使用され、データクリーニング機能も提供します。パンダを使用してExcelデータを操作するのは非常に簡単になります。

 

パンダのインストール

# pandas默认依赖xlrd库,故先安装xlrd
pip install xlrd

# 安装Pandas
pip install Pandas

 

パンダの構文

import Pandas as pd

# 首先初始化,engine默认是xlrd
s = pd.ExcelFile(path_or_buffer, engine=None)



# 接着parse
s.parse(sheet_name=0,header=0,names=None,index_col=None,usecols=None,

squeeze=False,converters=None,true_values=None,false_values=None,

skiprows=None,nrows=None,na_values=None,parse_dates=False,

date_parser=None,thousands=None,comment=None,skipfooter=0,

convert_float=True,mangle_dupe_cols=True,**kwds,)

PandasはExcelファイルを非常に簡単に読み取ります。最初に、Pandasを使用してExcelFileを初期化します。2つのパラメーターpath_or_bufferは、読み取りたいファイルのパスです。

Excelファイル名には、中国語ではなく、英語のパスと英語の命名方法を使用することをお勧めします。

import pandas as pd

path_or_buffer = r'D:\Python_Test\APITest\tests_pytest_ddt\test_baidu_ddt.xlsx'

engineは、Pandasが使用するエンジンです。使用可能なオプションは、「xlrd」、「openpyxl」、「odf」、および「pyxlsb」です。指定されていない場合、デフォルトでxlrdが使用されます。

 

解析関数のパラメーターが
初期化された後、s.parse()関数を使用できます。解析関数には多くのパラメーターがあり、ここでは一般的に使用されるいくつかのパラメーターのみをリストします。

 

sheet_name:Excelのシート名
sheet_nameは、整数、リスト名、またはその2つの組み合わせにすることができます。

# 通过整型数字读取。读取第一个sheet。Pandas sheet名下标以0开始
s = pd.ExcelFile(path_or_buffer, sheet_name = 0)

# 通过列表名读取
data = s.parse(sheet_name = 'Testing')

# 通过index读取。读取第一个sheet
data = s.parse(sheet_name = 0)

#组合读取。读取第4个sheet,名为Testing的sheet以及第7个sheet
data = s.parse(sheet_name = [3, 'Testing', 'Sheet6'])

 

ヘッダー:列名として使用する行。
ヘッダーデフォルト値最初の行である0です。[0、x]に設定することもできます。
(たとえば、[0,1]は、最初の2行を複数のインデックスとして使用することを意味します)

data = s.parse(sheet_name = 'Testing', header = 0)

注:Pandasはデフォルトでヘッダーの最初の行を使用するため、Excelでは最初の行をタイトルにする必要があります。最初の行がデータの場合、データの最初の行は省略されます。ヘッダーが必要ない場合は、パラメーターとしてheader = Noneを渡すことができます。

 

usecols:読み取られる列
usecolsは、[0、1、2]などの0から始まる整数、または列AからDを読み取ることを意味する "A:D、F"などの列名と列を受け取ります。 F。

data = s.parse(sheet_name = 'Testing', usecols='A:D')

 

skiprows:読み取るとき、特定の行をスキップします
skiprows = n、最初のn行をスキップします; skiprows = [a、b、c]、行をスキップしますa + 1、b + 1、c + 1(インデックスは0から始まります)

data = s.parse(sheet_name = 'iTesting', skiprows = [1,2,3])

 

nrows:
読み取られる数、読み取られるのみ

data = s.parse(sheet_name = 'Testing', nrows = 3)

 

PandasとPytestを組み合わせて、データ駆動型を実現

Pandasの構文を理解したら、Pandasを使用してExcelデータを読み取る方法を見てみましょう。

def test_read_data_from_pandas(excel_file, sheet_name):

    if not os.path.exists(excel_file):
        raise ValueError("File not exists")

    # 初始化
    s = pd.ExcelFile(excel_file)

    # 解析Excel Sheet
    df = s.parse(sheet_name)

    # 以list格式返回数据
    return df.values.tolist()

ご覧のとおり、パンダを使用してExcelデータを読み取る方が簡潔で便利です。
最後に、test_baidu_ddt.pyファイルを更新しましょう。更新されたコードは次のとおりです。

import codecs
import json
import os
import time
import pytest
import yaml
from openpyxl import load_workbook
import pandas as pd

# 读取Yaml文件和Json文件
def test_read_data_from_json_yaml(data_file):
    return_value = []
    data_file_path = os.path.abspath(data_file)
    print(data_file_path)

    _is_yaml_file = data_file_path.endswith((".yml", ".yaml"))
    with codecs.open(data_file_path, 'r', 'utf-8') as f:
        #从YAML或JSON文件中加载数据
        if _is_yaml_file:
            data = yaml.safe_load(f)
        else:
            data = json.load(f)

    for i, elem in enumerate(data):
        if isinstance(data, dict):
            key, value = elem, data[elem]
            if isinstance(value, dict):
                case_data = []
                for v in value.values():
                    case_data.append(v)
                return_value.append(tuple(case_data))
            else:
                return_value.append((value,))
    return return_value

# 读取Excel 文件 -- openpyxl
def test_read_data_from_excel(excel_file, sheet_name):
    return_value = []

    if not os.path.exists(excel_file):
        raise ValueError("File not exists")

    wb = load_workbook(excel_file)
    for s in wb.sheetnames:
        if s == sheet_name:
            sheet = wb[sheet_name]
            for row in sheet.rows:
                return_value.append([col.value for col in row])
    print(return_value)
    return return_value[1:]

# 读取Excel文件 -- Pandas
def test_read_data_from_pandas(excel_file, sheet_name):
    if not os.path.exists(excel_file):
        raise ValueError("File not exists")
    s = pd.ExcelFile(excel_file)
    df = s.parse(sheet_name)
    return df.values.tolist()

@pytest.mark.baidu
class TestBaidu:

    @pytest.mark.parametrize('search_string, expect_string',  test_read_data_from_pandas(r'D:\Python_Test\APITest\tests_pytest_ddt\test_baidu_ddt.xlsx', 'Testing'))
    def test_baidu_search(self, login, search_string, expect_string):
        driver, s, base_url = login
        driver.get(base_url + "/")
        driver.find_element_by_id("kw").send_keys(search_string)
        driver.find_element_by_id("su").click()
        time.sleep(2)

        search_results = driver.find_element_by_xpath('//*[@id="1"]/h3/a').get_attribute('innerHTML')
        print(search_results)
        assert (expect_string in search_results) is True


if __name__ == "__main__":
    pytest.main(['-s', '-v', 'tests_pytest_ddt'])

次のように、コマンドラインで再度実行します。

D:\Python_Test\APITest>pytest tests_pytest_ddt -s -v

実行後に結果を確認すると、テストが正しく実行され、ExcelでPandasを介して指定されたシート名からテストデータが取得されていることがわかります。


実際、PandasはExcelファイルだけでなく、HTMLファイル、TXTファイル、JSONファイル、データベースファイル(.sql)なども読み取ることができます。データ分析の分野では、パンダが広く使用されています。パンダの具体的な使用法については、ご自身で参照してください。

[The Way of Infinite Testing]パブリックアカウントへようこそ、返信[Receive Resources]
Pythonプログラミング学習リソース乾物、
Python + AppiumフレームワークAPPUI自動化、
Python + Seleniumフレームワーク
WebUI自動化、Python + UnittestフレームワークAPI自動化、

リソースとコードは無料で送信されます〜
記事の下部に公式アカウントのQRコードがあります。WeChatでスキャンしてフォローするだけです。

備考:私の個人公開アカウントが正式に開設され、ビッグデータテスト、機能テスト、テスト開発、APIインターフェイスの自動化、テストの運用と保守、UI自動化テストなどのテストテクノロジーの共有に専念しています。WeChat検索パブリックアカウント:「WuliangThe Way of Testing」、または以下のQRコードをスキャンしてください。

 注意を向けて、一緒に成長しましょう!

おすすめ

転載: blog.csdn.net/weixin_41754309/article/details/113662924