データ駆動型テスト フレームワーク構築の段階的なプロセスと概要
呉氏から自動化されたデータドリブンフレームワークの構築を学んだ後、私が独学で実践する際には、このデータドリブンフレームワークを実装するために、シンプルなプログラムを少しずつ拡張、最適化することを試みました。
まず、自動テスト フレームワークを構築する目的について話しましょう。
1つは、回帰テストの繰り返し実行など、手作業による繰り返し作業を自動プログラムで代替し効率化することで、機能の自動運用を実現し、毎回手動で繰り返しの作業を行わなくても済むようにすることです。
2 つ目は、データとデータに対する操作をカプセル化し、コードの繰り返しの記述を減らし、テスト データとプログラムを分離して、自動テスターがコードにあまり注意を払わなくても済むようにすることです。
データを適切に維持することにより、効果的な自動テストの実行、良好な再利用性、その他多くの利点が得られます。。。
このフレームワークをゼロから構築した後のプロセスの概要について話しましょう。
まず実装したい関数をファイルに実装し、次に分散している特定の関数をカプセル化し、メインプログラム内でカプセル化されたメソッドを呼び出し、プロセス全体を複数のステップに分割し、各ステップで 1 つのカプセル化または最適化のみを実装します。
ビルディングブロックを配置するのと同じように、場所が完成したら、このノードに立って、次に何をカプセル化して最適化できるかを考えてから、一歩前進し、その上で何が最適化できるかを検討します。
テストフレームワークを構築するまでは、まずフレームワークの構造からプロセスを切り離し、フレームワークがどうなるかを考えるのではなく、既存のプログラムでどのようなカプセル化や最適化ができるのか、どう変更するのかを考えるだけです。より使いやすくするためのものです。
より整理されたように見えますので、どの部分を抽出して別のパッケージを作成できるかを考えたときに、いくつかのフレームワーク構造を比較し、このタイプのパッケージはどのようなパッケージに配置できるかを考え、パッケージを最適化して分類します。同じ時間です。
プログラムをカプセル化して構成ファイルに配置すると、最終的にこのプロセスで得られるのはテスト フレームワークであることがわかります。
このプロセスが完了すると、最初から最適化してカプセル化すると、最終的にこれらのモジュールが得られるため、テスト フレームワークの全体的なアーキテクチャから各モジュールの機能を理解するのがはるかに簡単になります。
その後、さまざまな種類のドライバーのテスト フレームワークを学習すると、原則は基本的に同じになります。
このフレームワークを構築する全体的なプロセスは
次のとおりです。 まず、達成したいのは、126 メールボックスにログインして連絡先を追加する機能であることは明らかです。
ステップ 1 -- フレームワークを使用せずにコードを直接リストする場合、どうすればそれを実現できますか? まずこれを完了してみましょう。pycharm -dataDrivenTestPractice1 で新しいプロジェクトを作成します。プロジェクトの下に新しい TestScript パッケージを作成
し
ます
。 TestScript パッケージの下の TestScript パッケージ Python ファイル
コード:
#encoding=utf-8
#author-Xia Xiaoxu
from selenium import webdriver
import time
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.common.Exceptions import TimeoutException、NoSuchElementException
import トレースバック
driver=webdriver.Firefox(executable_path='c:\\geckodriver')
driver.get('http://mail.126.com')
try:
wait=WebDriverWait(driver ,10,0.2)#待機中の番組を表示
driver.switch_to.frame(driver.find_element_by_xpath("//iframe[@id='x-URS-iframe']"))#ユーザー名とパスワードの入力ボックスがあるフレーム要素に切り替える name=wait.until (lambda x
: x.find_element_by_xpath("//input[@placeholder='メールアカウントまたは携帯電話番号' and @name='メール']")) name.send_keys('
xiaxiaoxu1987')
パスワード=wait.until(lambda x:x.find_element_by_xpath ("//input[@placeholder='password']"))password.send_keys('gloryroad'
)
submit=wait.until(lambda x:x.find_element_by_xpath("//a[@id= 'dologin']" ))
submit.click()
driver.switch_to.default_content()#pycharm で switch_to_default_content() を使用すると取り消し線になり、
time.sleep(5) は
driver.page_source で u"exit" をアサートします。「page_source には存在しません」
address_book_link=wait.until(lambda x:x.find_element_by_xpath("//div[text()='通讯录']"))
address_book_link.click()
#assert u"新建联系人" in driver.page_source
add_contact_button=wait .until(lambda x:x.find_element_by_xpath("//span[text()='新建联系人']"))
add_contact_button.click()
contact_name=wait.until(lambda x:x.find_element_by_xpath("//a [@title='编辑详细姓名']/preceding-sibling::div/input"))
contact_name.send_keys(u"徐凤钗")
contact_email=wait.until(lambda x:x.find_element_by_xpath("//*[@ id='iaddress_MAIL_wrap']//input"))
contact_email.send_keys("[email protected]")
contact_is_star=wait.until(lambda x:x.find_element_by_xpath("//span[text()='スター接点として設定']/preceding-sibling::span/b"))
contact_is_star.click()
contact_mobile=wait.until(lambda x:x.find_element_by_xpath("//*[@id='iaddress_TEL_wrap']//dd//input")) contact_mobile.send_keys(
'18141134488')
contact_other_info=wait .until(lambda x:x.find_element_by_xpath("//textarea"))
contact_other_info.send_keys('私の妻')
contact_save_button=wait.until(lambda x:x.find_element_by_xpath("//span[.='确定' ]"))
contact_save_button.click()
例外 TimeoutException、e:
# 捕获TimeoutException异常
print trackback.print_exc()
例外 NoSuchElementException、e:
# 捕获NoSuchElementException异常
print trackback.print_exc()
例外例外、e:
#他の例外をキャッチする
print traceback.print_exc()
結果: ログインと連絡先の追加は OK
C:\Python27\python.exe D:/test/dataDrivenTestPractice1/TestScript.py
プロセスは終了コード 0 で終了しました
これで最初のステップが実装されたので、次に、このプログラム内のプログラムとデータを分離する方法を見てみましょう。
プログラムの主な機能を見てみましょう。
メールアドレスにログイン --> 連絡先ページを開く --> 連絡先の追加ボタンをクリック --> ポップアップ ウィンドウに連絡先情報を入力 --> 保存ボタンをクリックします。
データドリブンの核心もある --> データとプログラムの分離
まず、メールボックスにログインする手順を個別に抽出してパッケージ化することができ、ログイン モジュールを暫定的に指定します。
次に、ログイン関数をカプセル化し、プログラム内で呼び出します。
ステップ 2 - ログイン関数を抽出してカプセル化し、メイン プログラムで呼び出します。
プロジェクトの下に新しい PageObject パッケージを作成します
PageObject パッケージの下に LoginPage の新しい Python ファイルを作成して、ログイン操作をカプセル化します。
コード:
#encoding=utf-8
#著者-夏暁徐
SeleniumインポートWebドライバーから
インポート時間
selenium.webdriver.support.ui から WebDriverWait をインポート
selenium.webdriver.common.by からインポート
selenium.common.Exceptions からインポート TimeoutException、NoSuchElementException
トレースバックをインポートする
クラスLoginPage(オブジェクト):
def __init__(self,driver):
self.driver=ドライバー
デフォルトログイン(自分自身):
試す:
wait = WebDriverWait(driver, 10, 0.2) # 表示待機中
self.driver.switch_to.frame(self.driver.find_element_by_xpath("//iframe[@id='x-URS-iframe']")) # ユーザー名とパスワードの入力ボックスがあるフレーム要素に切り替えます
name = wait.until(lambda x: x.find_element_by_xpath("//input[@placeholder='電子メール アカウントまたは携帯電話番号' and @name='電子メール']"))
name.send_keys('xiaxiaoxu1987')
パスワード = wait.until(lambda x: x.find_element_by_xpath("//input[@placeholder='密码']"))
パスワード.send_keys('グローリーロード')
submit = wait.until(lambda x: x.find_element_by_xpath("//a[@id='dologin']"))
submit.click()
self.driver.switch_to.default_content() # pycharmでswitch_to_default_content()を使うと取り消し線になってアウトになります。
タイムスリープ(5)
self.driver.page_source で u「退出」をアサート、「page_source には存在しません」
TimeoutException を除く、e:
#TimeoutException 例外をキャッチ
印刷トレースバック.print_exc()
NoSuchElementException を除く、e:
#NoSuchElementException 例外をキャッチする
印刷トレースバック.print_exc()
例外を除く、e:
#他の例外をキャッチする
印刷トレースバック.print_exc()
__name__=="__main__"の場合:
driver=webdriver.Firefox(executable_path='c:\\geckodriver')
driver.get("http:\\mail.126.com")
login=ログインページ(ドライバー)
ログイン.ログイン()
結果: ログイン成功
C:\Python27\python.exe D:/test/dataDrivenTestPractice1/PageObject/Login_page.py
プロセスは終了コード 0 で終了しました
この時点でログイン関数はカプセル化されているので、次にメインプログラムを変更して LoginPage を呼び出します。
テストスクリプト.py:
#encoding=utf-8
#著者-夏暁徐
SeleniumインポートWebドライバーから
インポート時間
selenium.webdriver.support.ui から WebDriverWait をインポート
selenium.webdriver.common.by からインポート
selenium.common.Exceptions からインポート TimeoutException、NoSuchElementException
トレースバックをインポートする
PageObject.Login_Page インポートから *
driver=webdriver.Firefox(executable_path='c:\\geckodriver')
driver.get('http://mail.126.com')
lp=ログインページ(ドライバー)
wait = WebDriverWait(driver, 10, 0.2) # 表示待機中
試す:
lp.login()
address_book_link=wait.until(lambda x:x.find_element_by_xpath("//div[text()='通讯录']"))
address_book_link.click()
#assert u「新しい連絡先」(driver.page_source)
add_contact_button=wait.until(lambda x:x.find_element_by_xpath("//span[text()='新しい連絡先']"))
add_contact_button.click()
contact_name=wait.until(lambda x:x.find_element_by_xpath("//a[@title='詳細な名前を編集']/preceding-sibling::div/input"))
contact_name.send_keys(u"徐凤钗")
contact_email=wait.until(lambda x:x.find_element_by_xpath("//*[@id='iaddress_MAIL_wrap']//input"))
contact_email.send_keys("[email protected]")
contact_is_star=wait.until(lambda x:x.find_element_by_xpath("//span[text()='スターコンタクトとして設定']/preceding-sibling::span/b"))
contact_is_star.click()
contact_mobile=wait.until(lambda x:x.find_element_by_xpath("//*[@id='iaddress_TEL_wrap']//dd//input"))
contact_mobile.send_keys('18141134488')
contact_other_info=wait.until(lambda x:x.find_element_by_xpath("//textarea"))
contact_other_info.send_keys('私の妻')
contact_save_button=wait.until(lambda x:x.find_element_by_xpath("//span[.='确定']"))
contact_save_button.click()
TimeoutException を除く、e:
#TimeoutException 例外をキャッチ
印刷トレースバック.print_exc()
NoSuchElementException を除く、e:
#NoSuchElementException 例外をキャッチする
印刷トレースバック.print_exc()
例外を除く、e:
#他の例外をキャッチする
印刷トレースバック.print_exc()
結果: 成功
C:\Python27\python.exe D:/test/dataDrivenTestPractice1/TestScript/TestScript.py
プロセスは終了コード 0 で終了しました
メインプログラムの観点から見ると、連絡先を追加するアクションもカプセル化できます。最初にこの部分をカプセル化しましょう。後で問題があれば、戻って推測できます。最初はこの考えに従って実行し、その後実行しますそれをまた。
ステップ 3 - 連絡先を追加する機能をカプセル化する
PageObject パッケージの下に新しい AddressBook Python ファイルを作成します。
コードアドレスブック.py:
#encoding=utf-8
#著者-夏暁徐
SeleniumインポートWebドライバーから
インポート時間
selenium.webdriver.support.ui から WebDriverWait をインポート
selenium.webdriver.common.by からインポート
selenium.common.Exceptions からインポート TimeoutException、NoSuchElementException
トレースバックをインポートする
PageObject.Login_Page インポートから *
クラスAddressBook(オブジェクト):
def __init__(self,driver):
self.driver=ドライバー
def add_contact(self):
試す:
wait = WebDriverWait(self.driver, 10, 0.2) # 表示待機中
address_book_link = wait.until(lambda x: x.find_element_by_xpath("//div[text()='通讯录']"))
address_book_link.click()
# driver.page_source で u「新しい連絡先」をアサートします
add_contact_button = wait.until(lambda x: x.find_element_by_xpath("//span[text()='新しい連絡先']"))
add_contact_button.click()
contact_name = wait. until(
lambda x: x.find_element_by_xpath("//a[@title='詳細な名前を編集']/preceding-sibling::div/input"))
contact_name.send_keys(u"徐凤钗")
contact_email = wait.until(lambda x: x.find_element_by_xpath("//*[@id='iaddress_MAIL_wrap']//input"))
contact_email.send_keys("[email protected]")
contact_is_star = wait.until(
lambda x: x.find_element_by_xpath("//span[text()='スター接点として設定']/preceding-sibling::span/b"))
contact_is_star.click()
contact_mobile = wait.until(lambda x: x.find_element_by_xpath("//*[@id='iaddress_TEL_wrap']//dd//input"))
contact_mobile.send_keys('18141134488')
contact_other_info = wait.until(lambda x: x.find_element_by_xpath("//textarea"))
contact_other_info.send_keys('私の妻')
contact_save_button = wait.until(lambda x: x.find_element_by_xpath("//span[.='确定']"))
contact_save_button.click()
TimeoutException を除く、e:
#TimeoutException 例外をキャッチ
印刷トレースバック.print_exc()
NoSuchElementException を除く、e:
#NoSuchElementException 例外をキャッチする
印刷トレースバック.print_exc()
例外を除く、e:
#他の例外をキャッチする
印刷トレースバック.print_exc()
__name__=="__main__"の場合:
driver=webdriver.Firefox(executable_path='c:\\geckodriver')
driver.get('http://mail.126.com')
lp=ログインページ(ドライバー)
lp.login()
ab=アドレスブック(ドライバー)
ab.add_contact()
結果: 成功
C:\Python27\python.exe D:/test/dataDrivenTestPractice1/PageObject/AddressBook.py
プロセスは終了コード 0 で終了しました
この時点で、連絡先を追加する関数は大まかにカプセル化されているので、メイン プログラムで呼び出します。
テストスクリプト.py:
#encoding=utf-8
#著者-夏暁徐
SeleniumインポートWebドライバーから
インポート時間
selenium.webdriver.support.ui から WebDriverWait をインポート
selenium.webdriver.common.by からインポート
selenium.common.Exceptions からインポート TimeoutException、NoSuchElementException
トレースバックをインポートする
PageObject.Login_Page インポートから *
PageObject.AddressBook インポートから *
driver=webdriver.Firefox(executable_path='c:\\geckodriver')
driver.get('http://mail.126.com')
loginPage=ログインページ(ドライバー)
addressBook=アドレスブック(ドライバー)
ログインページ.login()
addressBook.add_contact()
結果: 成功
C:\Python27\python.exe D:/test/dataDrivenTestPractice1/TestScript/TestScript.py
プロセスは終了コード 0 で終了しました
この時点で、プログラムの 2 つの機能 (ログインと連絡先の追加) は大まかにカプセル化されています。この機能はメイン プログラムで直接呼び出すことができます。プログラムの主な機能を確認してみましょう:
メールアドレスにログイン --> 連絡先ページを開く --> 連絡先の追加ボタンをクリック --> ポップアップ ウィンドウに連絡先情報を入力 --> 保存ボタンをクリックします。データドリブンの核心もある --> データとプログラムの分離
次に、データの一部を抽出してみますが、このデータをどのように分離するかを見てみましょう。
プログラムの観点から見ると、データを呼び出す部分は、カプセル化されたばかりの 2 つのモジュール、Login_Page と AddressBook 内にあります。プログラムがデータをどのように使用するかを見てみましょう。
ログインページ:
住所録:
これら 2 つの関数をカプセル化するとき、パラメータは省略されず、関数内に直接書き込まれます。これは明らかに比較的低い値ですが、どうすればよいでしょうか? 関数内で呼び出す必要があるデータをパラメーターに置き換えて、呼び出し時にパラメーターを渡してみましょう。
まずはログイン関数を変更して、パラメータを使用するように変更する方法を見てみましょう。。。
パラメータ転送を使用する場合は、ログイン関数を分割する必要があります。カプセル化できるログイン関数のいくつかの部分があることがわかります。たとえば、フレーム要素の関数を検索し、ユーザー名の関数を検索します。 input box要素を入力し、単一の要素を検索します。要素の関数では、検索用のパラメータにデータを渡すことができます。
ステップ 4 - 要素を検索する機能をカプセル化する
LoginPage.py を変更します。
#encoding=utf-8
#著者-夏暁徐
SeleniumインポートWebドライバーから
インポート時間
selenium.webdriver.support.ui から WebDriverWait をインポート
selenium.webdriver.common.by からインポート
selenium.common.Exceptions からインポート TimeoutException、NoSuchElementException
トレースバックをインポートする
クラスLoginPage(オブジェクト):
def __init__(self,driver):
self.driver=ドライバー
self.wait = WebDriverWait(self.driver, 10, 0.2) # 待機中を表示
def getFrame(self,locateType,locateExpression):
Frame=self.wait.until(lambda x: x.find_element(by=locateType,value=locateExpression))#"//iframe[@id='x-URS-iframe']"
リターンフレーム
def getUserName(self,locateType,locateExpression):
userName=self.wait.until(lambda x: x.find_element(by=locateType,value=locateExpression))#"//input[@placeholder='電子メール アカウントまたは携帯電話番号' and @name='電子メール']"
ユーザー名を返す
def getPassword(self,locateType,locateExpression):
パスワード=self.wait.until(lambda x: x.find_element(by=locateType,value=locateExpression))#"//input[@placeholder='密码']"
パスワードを返す
def getLoginButton(self,locateType,locateExpression):
loginButton=self.wait.until(lambda x: x.find_element(by=locateType,value=locateExpression))#"//a[@id='dologin']"
ログインボタンを返す
__name__=="__main__"の場合:
driver=webdriver.Firefox(executable_path='c:\\geckodriver')
driver.get("http:\\mail.126.com")
lp=ログインページ(ドライバー)
driver.switch_to.frame(lp.getFrame("xpath","//iframe[@id='x-URS-iframe']"))
タイムスリープ(2)
lp.getUserName("xpath","//input[@placeholder='メールアカウントまたは携帯電話番号' and @name='メール']").clear()
lp.getUserName("xpath","//input[@placeholder='電子メール アカウントまたは携帯電話番号' and @name='電子メール']").send_keys("xiaxiaoxu1987")
lp.getPassword("xpath","//input[@placeholder='密码']").send_keys("gloryroad")
lp.getLoginButton("xpath","//a[@id='dologin']").click()
driver.switch_to.default_content()
タイムスリープ(5)
driver.page_source で u「退出」をアサート、「page_source には存在しません」
結果: ログイン成功
この時点で、要素を検索する各関数にパラメータとしてデータが渡されるのですが、問題が発生します。
電話をかけるときに、要素を見つけるために必要なデータを手動で入力する必要があり、さらに面倒です。間違った文字を入力すると、要素が見つからなくなります。どうすればよいですか?
再カプセル化し、データをファイルに配置し、ファイルからデータを読み取るメソッドをカプセル化する必要があります。この方法では、データを保存する構成ファイルを作成してから、新しい Python を作成する必要があります。ファイルを使用して、構成ファイルを読み取るメソッドをカプセル化します。
ステップ 5 - データを構成ファイルに入力し、ファイルからデータを読み取るメソッドをカプセル化します。
プロジェクトの下に Conf という名前の新しいパッケージを作成します (構成関連ファイルの保存に使用されます)。
Conf パッケージの下に新しいファイルを作成します: PageObjectRepository.ini
PageObjectRepository.ini :
[126mail_ログイン]
login_page.frame=id>x-URS-iframe
login_page.username=xpath>//input[@name='email']
login_page.password=xpath>//input[@name='パスワード']
login_page.loginbutton=id>dologin
[126mail_ホームページ]
home_page.addressbook=xpath>//div[text()='アドレス帳']
[126mail_addcontactsページ]
addcontacts_page.createcontactsbtn=xpath>//span[text()='新しい連絡先']
addcontacts_page.contactpersonname=xpath>//a[@title='詳細な名前を編集']/preceding-sibling::div/input
addcontacts_page.contactpersonemail=xpath>//*[@id='iaddress_MAIL_wrap']//input
addcontacts_page.starcontacts=xpath>//span[text()='スターコンタクトとして設定']/preceding-sibling::span/b
addcontacts_page.contactpersonmobile=xpath>//*[@id='iaddress_TEL_wrap']//dd//input
addcontacts_page.contactpersoncomment=xpath>//textarea
addcontacts_page.savecontaceperson=xpath>//span[.='OK']
プロジェクトの下に新しい Util パッケージを作成します。このパッケージは通常、構成ファイルの読み取り、要素メソッドの検索、Excel 操作クラス、時間クラス、ログ メソッドと操作、スクリーンショット、レポート テンプレートなどのツール クラスを保存するために使用されます。
Util パッケージの下に新しい Python ファイルを作成します: ParsePageObjectRepository.py で、構成ファイルを読み取るためのクラスをカプセル化します。
#encoding=utf-8
#著者-夏暁徐
ConfigParser から ConfigParser をインポート
クラス ParsePageObjectRepositoryConfig(オブジェクト):
def __init__(self,config_path):
self.cf=ConfigParser()#パーサーの生成
self.cf.read(config_path)
def getItemSection(self,sectionName):
print self.cf.items(セクション名)
return dict(self.cf.items(セクション名))
def getOptionValue(self,sectionName,optionName):#辞書を返す
print self.cf.get(セクション名,オプション名)
return self.cf.get(セクション名,オプション名)
__name__=='__main__' の場合:
pp=ParsePageObjectRepositoryConfig( "D:\\test\\dataDrivenTestPractice1\\Conf\\PageObjectRepository.ini" )
print pp.getItemSection("126mail_login")
print pp.getOptionValue("126mail_login","login_page.username")
結果: OK
C:\Python27\python.exe D:/test/dataDrivenTestPractice1/Util/ParsePageObjectRepository.py
[('login_page.frame', 'id>x-URS-iframe'), ('login_page.username', "xpath>//input[@name='email']"), ('login_page.password', "xpath>//input[@name='password']"), ('login_page.loginbutton', 'id>dologin')]
{'login_page.loginbutton': 'id>dologin', 'login_page.username': "xpath>//input[@name='email']", 'login_page.frame': 'id>x-URS-iframe' , 'login_page.password': "xpath>//input[@name='password']"}
xpath>//input[@name='email']
xpath>//input[@name='email']
プロセスは終了コード 0 で終了しました
テストコードでread関数を呼び出す際に設定ファイルへのパスをパラメータに手動で入力する必要があることがわかりますが、長い文字ですのでパスを変更する場合はここで変更する必要があります。すべてここにカプセル化されているので、ここで変更するのは簡単です。慎重に変数にパスを設定してください。
一般に、ファイル パスを格納する変数は、ProjectVar パッケージの下の var.py ファイルに配置する必要があります。その後、すべての構成ファイルのパスは、このファイル内の変数の形式で維持されます。相対パスは、パス、より安全です。
ステップ 6 - 変数を使用して構成ファイルへのパスを保存する
プロジェクトの下に新しい ProjectVar パッケージを作成します
ProjectVar パッケージの下に var.py の新しい Python ファイルを作成します。
var.py:
#encoding=utf-8
#著者-夏暁徐
私たちを輸入してください
#プロジェクトが存在するディレクトリの絶対パスを取得します
project_path=os.path.dirname(os.path.dirname(__file__))
#ページオブジェクトライブラリファイルの絶対パスを取得
page_object_repository_path=project_path.decode("utf-8")+u"/conf/PageObjectRepository.ini"
__name__=='__main__' の場合:
#テストコード
print "プロジェクトパス:", プロジェクトパス
print "ページオブジェクトリポジトリパス:",ページオブジェクトリポジトリパス
print os.path.exists(project_path)
print os.path.exists(page_object_repository_path)
結果:
C:\Python27\python.exe D:/test/dataDrivenTestPractice1/ProjectVar/var.py
プロジェクトパス: D:/test/dataDrivenTestPractice1
page_object_repository_path: D:/test/dataDrivenTestPractice1/conf/PageObjectRepository.ini
真実
真実
プロセスは終了コード 0 で終了しました
次に、ParsePageObjectRepository.py で構成ファイルの読み取りの実行をテストします。
ParsePageObjectRepository.py:
#encoding=utf-8
#著者-夏暁徐
ConfigParser から ConfigParser をインポート
from ProjectVar.var import page_object_repository_path#新しく追加されました
クラス ParsePageObjectRepositoryConfig(オブジェクト):
def __init__(self):#config_path パラメータを削除しました
self.cf=ConfigParser()#パーサーの生成
self.cf.read(page_object_repository_path)#変数に直接置換
def getItemSection(self,sectionName):
print self.cf.items(セクション名)
return dict(self.cf.items(セクション名))
def getOptionValue(self,sectionName,optionName):#辞書を返す
print self.cf.get(セクション名,オプション名)
return self.cf.get(セクション名,オプション名)
__name__=='__main__' の場合:
pp=ParsePageObjectRepositoryConfig()#設定ファイルのアドレス変数がコンストラクターで初期化されました
print pp.getItemSection("126mail_login")
print pp.getOptionValue("126mail_login","login_page.username")
結果: OK
C:\Python27\python.exe D:/test/dataDrivenTestPractice1/Util/ParsePageObjectRepository.py
[('login_page.frame', 'id>x-URS-iframe'), ('login_page.username', "xpath>//input[@name='email']"), ('login_page.password', "xpath>//input[@name='password']"), ('login_page.loginbutton', 'id>dologin')]
{'login_page.loginbutton': 'id>dologin', 'login_page.username': "xpath>//input[@name='email']", 'login_page.frame': 'id>x-URS-iframe' , 'login_page.password': "xpath>//input[@name='password']"}
xpath>//input[@name='email']
xpath>//input[@name='email']
次に、login.py ファイル内の呼び出しを修正し、手動で入力する必要があるすべてのパラメータを構成ファイルの読み取りに置き換えます。
login.py を変更します。
#encoding=utf-8
#著者-夏暁徐
SeleniumインポートWebドライバーから
インポート時間
selenium.webdriver.support.ui から WebDriverWait をインポート
selenium.webdriver.common.by からインポート
selenium.common.Exceptions からインポート TimeoutException、NoSuchElementException
トレースバックをインポートする
from Util.ParsePageObjectRepository import *#新加
from ProjectVar.var import *#新規追加
クラスLoginPage(オブジェクト):
def __init__(self,driver):
self.driver=ドライバー
self.parse_config_file=ParsePageObjectRepositoryConfig()#新規追加、設定ファイル情報の取得
self.login_page_items=self.parse_config_file.getItemSection("126mail_login")#新規加
print "self.login_page_items:",self.login_page_items
self.wait = WebDriverWait(self.driver, 10, 0.2) # 待機中を表示
def getFrame(self):#パラメータを削除して内部で処理します
locateType,locateExpression=self.login_page_items['login_page.frame'].split('>')#id>x-URS-iframe
Frame=self.wait.until(lambda x: x.find_element(by=locateType,value=locateExpression))#"//iframe[@id='x-URS-iframe']"
リターンフレーム
def getUserName(self): #パラメータを削除して内部で処理します
locateType、locateExpression = self.login_page_items['login_page.username'].split('>')#xpath>//input[@name='email']
userName=self.wait.until(lambda x: x.find_element(by=locateType,value=locateExpression))#"//input[@placeholder='電子メール アカウントまたは携帯電話番号' and @name='電子メール']"
ユーザー名を返す
def getPassword(self): #パラメータを削除して内部で処理します
locateType,locateExpression = self.login_page_items['login_page.password'].split('>')#xpath>//input[@name='password']
パスワード=self.wait.until(lambda x: x.find_element(by=locateType,value=locateExpression))#"//input[@placeholder='密码']"
パスワードを返す
def getLoginButton(self): #パラメータを削除して内部で処理します
locateType、locateExpression = self.login_page_items['login_page.loginbutton'].split('>') #id>dologin
loginButton=self.wait.until(lambda x: x.find_element(by=locateType,value=locateExpression))#"//a[@id='dologin']"
ログインボタンを返す
__name__=="__main__"の場合:
driver=webdriver.Firefox(executable_path='c:\\geckodriver')
driver.get("http:\\mail.126.com")
lp=ログインページ(ドライバー)
driver.switch_to.frame(lp.getFrame())
タイムスリープ(2)
lp.getユーザー名().clear()
lp.getUserName().send_keys("xiaxiaoxu1987")
lp.getPassword().send_keys("グローリーロード")
lp.getLoginButton().click()
driver.switch_to.default_content()
タイムスリープ(5)
driver.page_source で u「退出」をアサート、「page_source には存在しません」
これまで、多くのものをカプセル化して、ログイン データを構成ファイルに入れて読み取れるようにしました。ただし、完璧になるまでにはまだ長い道のりがありますが、問題はありません。明確な情報がある限り、このフレームワークに最適化する必要がある問題があるかどうかを見てみましょう。
次の 2 点が最適化できることがわかります。
1-login_page.py ファイル内のログイン ページ要素を取得する方法では、要素を見つけるための次の手順をカプセル化できます。
self.wait.until(lambda x: x.find_element(by=locateType,value=locateExpression)) の場合、要素を検索するすべてのメソッドでこれを記述する必要はありません。要素を検索するこのステップは連絡先を追加するプロセスにあります。関数内でも使用されますが、要素の検索メソッドをカプセル化するとさらに便利になります。
2-2 番目に、ログイン操作を実行するときに、ユーザー名とパスワードの情報を手動で入力します。これはカプセル化することもできます。カプセル化する方法は? 初期の login.py ファイル内の各メソッドがログイン情報を取得します。必要な要素については、ログイン操作を実行するときにこれらのメソッドを手動で呼び出します。要素を取得した後、文字を入力するか、クリックしてログイン操作を完了します。その後、これらの手順を別のファイルで実行できます。カプセル化とは、端的に言えば、各要素を取得するメソッドをカプセル化することですログイン機能を実現するためにlogin_pageに要素を追加します 散在するメソッドを毎回自分で整理する必要はありません ボックスに入れておきます ボックスの名前はloginです 毎回このボックスを実行するだけですので気にする必要はありません内部の詳細、パッケージはすべて同じです。
ステップ 7 - 要素を検索する機能をカプセル化し、さらにログイン機能をカプセル化します。
初期フレーム構造からわかるように、要素を見つけるメソッドは Util パッケージに配置できます。
Util パッケージに新しい ObjectMap.py ファイルを作成します。
オブジェクトマップ.py:
#encoding=utf-8
#著者-夏暁徐
selenium.webdriver.support.ui から WebDriverWait をインポート
#単一要素オブジェクトを取得する
def getElement(ドライバー,locateType,locateExpression):
試す:
element=WebDriverWait(driver,10).until(lambda x:x.find_element(by=locateType,value=locateExpression))
戻り要素
例外、e を除く:
上げる
#複数の同一のページ要素オブジェクトを取得し、リストとして返す
def getElements(ドライバー,locateType,locatorExpression):
試す:
elements=WebDriverWait(driver,5).until(lambda x:x.find_elements(by=locateType,value=locateExpression))
要素を返す
例外、e を除く:
上げる
__name__=="__main__"の場合:
#テストコード
SeleniumインポートWebドライバーから
driver=webdriver.Firefox(executable_path='c:\\geckodriver')
driver.get('http://www.baidu.com')
searchBox=getElement(driver,"xpath","//input[@id='kw']")
driver.quit()
結果: OK
C:\Python27\python.exe D:/test/dataDrivenTestPractice1/Util/ObjectMap.py
プロセスは終了コード 0 で終了しました
この時点で、要素を検索するメソッドがカプセル化されているので、要素を検索する各メソッドを実装するための ObjectMap メソッドを呼び出すように Login_Page.py を変更し、ログイン アクションをカプセル化しましょう。
ログインページ.py:
#encoding=utf-8
#著者-夏暁徐
SeleniumインポートWebドライバーから
インポート時間
selenium.webdriver.support.ui から WebDriverWait をインポート
selenium.webdriver.common.by からインポート
selenium.common.Exceptions からインポート TimeoutException、NoSuchElementException
トレースバックをインポートする
Util.ParsePageObjectRepository からインポート *
ProjectVar.var からインポート *
Util.ObjectMap インポートから *
クラスLoginPage(オブジェクト):
def __init__(self,driver):
self.driver=ドライバー
self.parse_config_file=ParsePageObjectRepositoryConfig()
self.login_page_items=self.parse_config_file.getItemSection("126mail_login")
print "self.login_page_items:",self.login_page_items
self.wait = WebDriverWait(self.driver, 10, 0.2) # 待機中を表示
def getFrame(self):
locateType,locateExpression=self.login_page_items['login_page.frame'].split('>')#id>x-URS-iframe
Frame=getElement(self.driver,locateType,locateExpression)#"//iframe[@id='x-URS-iframe']"
リターンフレーム
def getUserName(self):
locateType、locateExpression = self.login_page_items['login_page.username'].split('>')#xpath>//input[@name='email']
userName=getElement(self.driver,locateType,locateExpression)#"//input[@placeholder='電子メール アカウントまたは携帯電話番号' and @name='電子メール']"
ユーザー名を返す
def getPassword(self):
locateType,locateExpression = self.login_page_items['login_page.password'].split('>')#xpath>//input[@name='password']
パスワード=getElement(self.driver,locateType,locateExpression)#"//input[@placeholder='秘密']"
パスワードを返す
def getLoginButton(self):
locateType、locateExpression = self.login_page_items['login_page.loginbutton'].split('>') #id>dologin
loginButton=getElement(self.driver,locateType,locateExpression)#"//a[@id='dologin']"
ログインボタンを返す
デフォルトログイン(自分自身):
self.driver.switch_to.frame(self.getFrame())
self.getUserName().clear()
self.getUserName().send_keys("xiaxiaoxu1987")
self.getPassword().send_keys("グローリーロード")
self.getLoginButton().click()
__name__=="__main__"の場合:
#テストコード
driver=webdriver.Firefox(executable_path='c:\\geckodriver')
driver.get("http:\\mail.126.com")
lp=ログインページ(ドライバー)
lp.login()
結果:ログインできました
C:\Python27\python.exe D:/test/dataDrivenTestPractice1/PageObject/Login_Page.py
self.login_page_items: {'login_page.loginbutton': 'id>dologin', 'login_page.username': "xpath>//input[@name='email']", 'login_page.frame': 'id>x- URS-iframe', 'login_page.password': "xpath>//input[@name='password']"}
プロセスは終了コード 0 で終了しました
次に、ログイン関数パッケージを Login_page.py から移動し、メソッドと呼び出しを分離するために別のファイルとして保存します。将来変更があった場合は、login_page.py を変更するだけです。
ステップ 8 - ログインメソッドを個別にカプセル化する
プロジェクトの下に新しいアクション パッケージを作成します
アクションパッケージの下に新しいlogin.pyを作成します。
ログイン.py:
#encoding=utf-8
#著者-夏暁徐
PageObject.Login_Page インポートから *
SeleniumインポートWebドライバーから
def ログイン(ドライバー、ユーザー名、パスワード):
lp=ログインページ(ドライバー)
driver.switch_to.frame(lp.getFrame())
lp.getユーザー名().clear()
lp.getUserName().send_keys(ユーザー名)
lp.getPassword().send_keys(パスワード)
lp.getLoginButton().click()
__name__=='__main__' の場合:
#テストコード
driver=webdriver.Firefox(executable_path='c:\\geckodriver')
driver.get("http://mail.126.com")
ログイン(ドライバー,"xiaxiaoxu1987","グローリーロード")
結果: ログイン成功
C:\Python27\python.exe D:/test/dataDrivenTestPractice1/Action/login.py
self.login_page_items: {'login_page.loginbutton': 'id>dologin', 'login_page.username': "xpath>//input[@name='email']", 'login_page.frame': 'id>x- URS-iframe', 'login_page.password': "xpath>//input[@name='password']"}
プロセスは終了コード 0 で終了しました
この時点で、ログイン機能は基本的にカプセル化され、データとプログラムが分離されています。データとプログラムの分離を実現するために、連絡先の追加のカプセル化を段階的に見てみましょう。連絡先の追加の操作は、先ほどのAddressBook.pyですが、冒頭のlogin_page.pyと同じ状況で、まだ要素の検索操作と設定ファイルのデータ読み込みができていないので、これを始めてみましょう。
ステップ 9 - 連絡先の追加操作をカプセル化する
アイデア:
AddressBook.py では、連絡先ページを追加するために必要な各要素をメソッドにカプセル化し、各要素に必要な xpath データを見つけて構成ファイルに配置し、関数を使用してこれらの要素のメソッドを呼び出して入力文字を実装します。またはクリック操作で連絡先を追加する機能を実装
AddressBook.py:
#encoding=utf-8
#著者-夏暁徐
SeleniumインポートWebドライバーから
インポート時間
selenium.webdriver.support.ui から WebDriverWait をインポート
selenium.webdriver.common.by からインポート
selenium.common.Exceptions からインポート TimeoutException、NoSuchElementException
トレースバックをインポートする
PageObject.Login_Page インポートから *
Action.login インポートから *
クラスAddressBook(オブジェクト):
def __init__(self,driver):
self.driver=ドライバー
self.parse_config_file=ParsePageObjectRepositoryConfig()
self.address_book_page=self.parse_config_file.getItemsFromSection("126mail_homepage")
print "self.address_book_page:",self.address_book_page
self.address_book_page_itmes=self.parse_config_file.getItemsFromSection("126mail_addcontactspage")
print "self.address_book_page_itmes:", self.address_book_page_itmes
def address_book_link(self):
locateType,locateExpression = self.address_book_page['home_page.addressbook'].split(">")
printlocateType,locateExpression
return getElement(self.driver,"xpath","//div[text()='アドレス帳']")
def add_contact_button(self):
locateType,locateExpression=self.address_book_page_itmes['addcontacts_page.createcontactsbtn'].split(">")
printlocateType,locateExpression
getElement(self.driver,locateType,locateExpression) を返す
デフォルト連絡先名(自分):
locateType,locateExpression=self.address_book_page_itmes['addcontacts_page.contactpersonname'].split(">")
printlocateType、locateExpression
return getElement(self.driver,locateType,locateExpression)
def contact_email(自分自身):
locateType、locateExpression = self.address_book_page_itmes['addcontacts_page.contactpersonemail'].split(">")
printlocateType、locateExpression
return getElement(self.driver,locateType,locateExpression)
def contact_is_star(自分):
locateType、locateExpression = self.address_book_page_itmes['addcontacts_page.starcontacts'].split(">")
printlocateType、locateExpression
return getElement(self.driver,locateType,locateExpression)
def contact_mobile(自分):
locateType、locateExpression = self.address_book_page_itmes['addcontacts_page.contactpersonmobile'].split(">")
printlocateType、locateExpression
return getElement(self.driver,locateType,locateExpression)
def contact_other_info(self):
locateType、locateExpression = self.address_book_page_itmes['addcontacts_page.contactpersoncomment'].split(">")
printlocateType、locateExpression
return getElement(self.driver,locateType,locateExpression)
def contact_save_button(self):
locateType、locateExpression = self.address_book_page_itmes['addcontacts_page.savecontaceperson'].split(">")
printlocateType、locateExpression
return getElement(self.driver,locateType,locateExpression)
__name__=="__main__"の場合:
driver = webdriver.Firefox(executable_path='c:\\geckodriver')
driver.get("http://mail.126.com")
login(ドライバー, "xiaxiaoxu1987", "gloryroad")
addressbook=アドレスブック(ドライバー)
タイムスリープ(5)
addressbook.address_book_link().click()
addressbook.add_contact_button().click()
addressbook.contact_name().send_keys("sam")
addressbook.contact_email().send_keys("[email protected]")
addressbook.contact_is_star().click()
addressbook.contact_mobile().send_keys("18142244444")
addressbook.contact_other_info().send_keys("自分")
addressbook.contact_save_button().click()
結果: OK
C:\Python27\python.exe D:/test/dataDrivenTestPractice1/PageObject/AddressBook.py
self.login_page_items: {'login_page.loginbutton': 'id>dologin', 'login_page.username': "xpath>//input[@name='email']", 'login_page.frame': 'id>x- URS-iframe', 'login_page.password': "xpath>//input[@name='password']"}
self.address_book_page: {'home_page.addressbook': "xpath>//div[text()='\xe9\x80\x9a\xe8\xae\xaf\xe5\xbd\x95']"}
self.address_book_page_itmes: {'addcontacts_page.createcontactsbtn': "xpath>//span[text()='\xe6\x96\xb0\xe5\xbb\xba\xe8\x81\x94\xe7\xb3\xbb\xe4\ xba\xba']", 'addcontacts_page.contactpersonmobile': "xpath>//*[@id='iaddress_TEL_wrap']//dd//input", 'addcontacts_page.contactpersonemail': "xpath>//*[@id ='iaddress_MAIL_wrap']//input", 'addcontacts_page.contactpersoncomment': 'xpath>//textarea', 'addcontacts_page.contactpersonname': "xpath>//a[@title='\xe7\xbc\x96\xe8\ xbe\x91\xe8\xaf\xa6\xe7\xbb\x86\xe5\xa7\x93\xe5\x90\x8d']/preceding-sibling::div/input", 'addcontacts_page.savecontaceperson': "xpath>/ /span[.='\xe7\xa1\xae \xe5\xae\x9a']", 'addcontacts_page.starcontacts':"xpath>//span[text()='\xe8\xae\xbe\xe4\xb8\xba\xe6\x98\x9f\xe6\xa0\x87\xe8\x81\x94\xe7\xb3\xbb\xe4 \xba\xba']/preceding-sibling::span/b"}
xpath //div[text()='アドレス帳']
xpath //span[text()='新しい連絡先']
xpath //a[@title='詳細な名前を編集']/preceding-sibling::div/input
xpath //*[@id='iaddress_MAIL_wrap']//input
xpath //span[text()='スター接点として設定']/preceding-sibling::span/b
xpath //*[@id='iaddress_TEL_wrap']//dd//input
xpath //テキストエリア
xpath //スパン[.='OK']
さて、お問い合わせページの各要素を追加する操作をカプセル化してテストコードで呼び出しました。ログイン関数のカプセル化と同様に、お問い合わせページの各要素を追加する操作を別のファイルにカプセル化しました。メインプログラム内で直接呼び出すだけなので操作が便利です。
ステップ 10 - addressBook の連絡先追加機能を個別にカプセル化する
Action パッケージの下に新しい add_contact.py ファイルを作成します。
add_contact.py:
#encoding=utf-8
#著者-夏暁徐
PageObject.AddressBook インポートから *
SeleniumインポートWebドライバーから
def add_contact(ドライバー):
driver.switch_to.default_content()
アドレスブック = アドレスブック(ドライバー)
addressbook.address_book_link().click()
addressbook.add_contact_button().click()
addressbook.contact_name().send_keys("sam")
addressbook.contact_email().send_keys("[email protected]")
addressbook.contact_is_star().click()
addressbook.contact_mobile().send_keys("18142244444")
addressbook.contact_other_info().send_keys("自分")
addressbook.contact_save_button().click()
__name__=='__main__' の場合:
driver=webdriver.Firefox(executable_path="c:\\geckodriver")
driver.get("http://mail.126.com")
login(ドライバー, "xiaxiaoxu1987", "gloryroad")
add_contact(ドライバー)
結果:
C:\Python27\python.exe D:/test/dataDrivenTestPractice1/Action/add_contact.py
self.login_page_items: {'login_page.loginbutton': 'id>dologin', 'login_page.username': "xpath>//input[@name='email']", 'login_page.frame': 'id>x- URS-iframe', 'login_page.password': "xpath>//input[@name='password']"}
プロセスは終了コード 0 で終了しました
さらにカプセル化し、入力部分をパラメータに置き換えます
#encoding=utf-8
#著者-夏暁徐
PageObject.AddressBook インポートから *
SeleniumインポートWebドライバーから
def add_contact(driver,name="",email="",is_star=True,mobile="",otherinfo=""):
driver.switch_to.default_content()
アドレスブック = アドレスブック(ドライバー)
addressbook.address_book_link().click()
addressbook.add_contact_button().click()
addressbook.contact_name().send_keys(name)
addressbook.contact_email().send_keys(email)
is_star==True の場合:
addressbook.contact_is_star().click()
addressbook.contact_mobile().send_keys(モバイル)
addressbook.contact_other_info().send_keys(otherinfo)
addressbook.contact_save_button().click()
__name__=='__main__' の場合:
driver=webdriver.Firefox(executable_path="c:\\geckodriver")
driver.get("http://mail.126.com")
login(ドライバー, "xiaxiaoxu1987", "gloryroad")
add_contact(ドライバー,"xiaxiaoxu","[email protected]",True,"13333334444","gloryroad")
driver.quit()
結果: OK
C:\Python27\python.exe D:/test/dataDrivenTestPractice1/Action/add_contact.py
self.login_page_items: {'login_page.loginbutton': 'id>dologin', 'login_page.username': "xpath>//input[@name='email']", 'login_page.frame': 'id>x- URS-iframe', 'login_page.password': "xpath>//input[@name='password']"}
プロセスは終了コード 0 で終了しました
この時点で、ほとんどの関数をカプセル化したので、メイン プログラムでこれらの関数を呼び出してみましょう。
テストスクリプト.py:
#encoding=utf-8
#著者-夏暁徐
SeleniumインポートWebドライバーから
インポート時間
selenium.webdriver.support.ui から WebDriverWait をインポート
selenium.webdriver.common.by からインポート
selenium.common.Exceptions からインポート TimeoutException、NoSuchElementException
トレースバックをインポートする
PageObject.Login_Page インポートから *
PageObject.AddressBook インポートから *
Action.add_contact import から *
Action.login インポートから *
driver=webdriver.Firefox(executable_path='c:\\geckodriver')
driver.get('http://mail.126.com')
login(ドライバー, "xiaxiaoxu1987", "gloryroad")
add_contact(ドライバー,"xiaxiaoxu","[email protected]",True,"13333334444","gloryroad")
driver.quit()
結果: 正常に動作します。
C:\Python27\python.exe D:/test/dataDrivenTestPractice1/TestScript/TestScript.py
プロセスは終了コード 0 で終了しました
メイン プログラムの呼び出しから判断すると、追加する必要があるユーザー名、パスワード、連絡先情報など、手動で入力する必要があるデータがまだいくつかあります。複数の連絡先を追加する必要がある場合は、それを入力する必要があります。次のステップ この部分のデータをプログラムから切り離してファイルに保存する方法を見てみましょう 今回はExcelに入れて、Excelを操作してデータを抽出する方法を考えます。
ステップ 11 - Excel 操作をカプセル化する
Excel ファイルを作成し、最初のシートに 126 個のアカウント情報を入力します。
2 番目のシートには連絡先が含まれています。
プロジェクトの下に新しい TestData パッケージを作成し、そのパッケージの下に Excel ファイルを置きます。
Excel.py:
#encoding=utf-8
#著者-夏暁徐
# エンコーディング=utf-8
openpyxlインポートload_workbookから
openpyxl.styles からボーダー、サイド、フォントをインポート
インポート時間
ProjectVar.var からインポート *
クラスparseExcel(オブジェクト):
def __init__(self, ExcelPath):
self.excelPath = エクセルパス
self.workbook =load_workbook(excelPath) #加ダウンロードexcel
self.sheet = self.workbook.active # 最初のシートを取得する
self.font = フォント(color=なし)
self.colorDict = {"赤": 'FFFF3030', "緑": 'FF008B00'}
#現在操作対象のシートオブジェクトを設定し、インデックスを使用して対応するシートを取得します
def set_sheet_by_index(self,sheet_index):
シート名 = self.workbook.get_sheet_names()[シートインデックス]
self.sheet = self.workbook.get_sheet_by_name(sheet_name)
self.sheet を返す
# 現在のデフォルトシートの名前を取得します
def get_default_sheet(self):
self.sheet.title を返す
#現在操作対象のシートオブジェクトを設定し、シート名を使用して対応するシートを取得します
def set_sheet_by_name(self,sheet_name):
シート = self.workbook.get_sheet_by_name(sheet_name)
self.sheet = シート
self.sheet を返す
# デフォルトシートの最大行数を取得します
def get_max_row_no(self):
self.sheet.max_row を返す
# デフォルトシートの最大列数を取得する
def get_max_col_no(self):
self.sheet.max_column を返す
# デフォルトシートの最小(開始)行番号を取得します
def get_min_row_no(self):
self.sheet.min_row を返す
# デフォルトシートの最小(開始)列番号を取得します
def get_min_col_no(self):
self.sheet.min_column を返す
# デフォルトシートのすべての行オブジェクトを取得します。
def get_all_rows(self):
リストを返す(self.sheet.iter_rows())
# return list(self.rows) も使用可能
# デフォルトシート内のすべての列オブジェクトを取得します
def get_all_cols(self):
リストを返す(self.sheet.iter_cols())
# return list(self.sheet.columns) も使用可能
# デフォルトのシートから列を取得します。最初の列は 0 から始まります
def get_single_col(self,col_no):
return self.get_all_cols()[col_no]
# デフォルトのシートから特定の行を取得します。最初の行は 0 から始まります
def get_single_row(self, row_no):
return self.get_all_rows()[row_no]
# デフォルトシートから、行番号と列番号を介して指定されたセルを取得します。行番号と列番号は 1 から始まることに注意してください
def get_cell(self、row_no、col_no):
return self.sheet.cell(row=row_no、column=col_no)
# デフォルトシートから、行番号と列番号を通じて指定されたセルの内容を取得します。行番号と列番号は 1 から始まることに注意してください
def get_cell_content(self, row_no,col_no):
return self.sheet.cell(row=row_no, column=col_no).value
# デフォルトシートから、行番号と列番号を通して指定したセルに指定した内容を書き込みます。行番号と列番号は 1 から始まることに注意してください
# このメソッドを呼び出すときは、Excel を開いてはいけません。
def write_cell_content(self、row_no、col_no、content、font=None):
self.sheet.cell(row=row_no、column=col_no).value = 内容
self.workbook.save(self.excelPath)
return self.sheet.cell(row=row_no, column=col_no).value
# デフォルトのシートから、指定したセルに行番号と列番号を使用して現在の日付を書き込みます。行番号と列番号は 1 から始まることに注意してください。
# このメソッドを呼び出すときは、Excel を開いてはいけません。
def write_cell_current_time(self、row_no、col_no):
time1 = time.strftime("%Y-%m-%d %H:%M:%S")
self.sheet.cell(row=row_no、column=col_no).value = str(time1)
self.workbook.save(self.excelPath)
return self.sheet.cell(row=row_no, column=col_no).value
def save_excel_file(self):
self.workbook.save(self.excelPath)
__name__ == '__main__'の場合:
#テストコード
p = parseExcel(test_data_excel_path)
print u"デフォルトシートを取得:", p.get_default_sheet()
print u"シート インデックスを 1 に設定"、p.set_sheet_by_index(1)
print u"デフォルトシートを取得:", p.get_default_sheet()
print u"シート インデックスを 0 に設定"、p.set_sheet_by_index(0)
print u"デフォルトシートを取得:", p.get_default_sheet()
print u"最大行数:", p.get_max_row_no()
print u"最大列数:", p.get_max_col_no()
print u"最小開始行番号:", p.get_min_row_no()
print u"最小開始列数:", p.get_min_col_no()
print u"すべての行オブジェクト:"、p.get_all_rows()
print u"すべての列オブジェクト:"、p.get_all_cols()
print u"特定の列を取得(2):", p.get_single_col(2)
print u"特定の行を取得(1):", p.get_single_row(1)
print u"行番号と列番号を取得(2,2) cell:", p.get_cell(2, 2)
print u"行番号と列番号のセルの内容を取得(2, 2)", p.get_cell_content(2, 2)
print u"行番号と列番号書き込み内容 (11,11): 'xiaxiaoxu'", p.write_cell_content(11, 11, 'xiaxiaoxu') #
print u"行番号と列番号が現在の日付 (13,13) に書き込まれます:", p.write_cell_current_time(13, 13)
結果: OK
C:\Python27\python.exe D:/test/dataDrivenTestPractice1/Util/Excel.py
デフォルトのシートを取得します: Contact
シート インデックスを 1 に設定します <Worksheet "\u8054\u7cfb\u4eba">
デフォルトのシートを取得します: Contact
シート インデックスを 0 に設定します <ワークシート "126\u8d26\u53f7">
デフォルトシートの取得: 126 アカウント
最大行数: 3
最大列数: 6
開始行の最小数: 1
開始列の最小数: 1
すべての行オブジェクト: [(<セル u'126\u8d26\u53f7'.A1>, <セル u'126\u8d26\u53f7'.B1>, <セル u'126\u8d26\u53f7'.C1>, <セルu'126\u8d26\u53f7'.D1>, <セル u'126\u8d26\u53f7'.E1>, <セル u'126\u8d26\u53f7'.F1>), (<セル u'126\u8d26\ u53f7'.A2>、<セル u'126\u8d26\u53f7'.B2>、<セル u'126\u8d26\u53f7'.C2>、<セル u'126\u8d26\u53f7'.D2>、<セルu'126\u8d26\u53f7'.E2>, <セル u'126\u8d26\u53f7'.F2>), (<セル u'126\u8d26\u53f7'.A3>, <セル u'126\u8d26\ u53f7'.B3>、<セル u'126\u8d26\u53f7'.C3>、<セル u'126\u8d26\u53f7'.D3>、<セル u'126\u8d26\u53f7'.E3>、<セルu'126\u8d26\u53f7'.F3>)]
すべての列オブジェクト: [(<セル u'126\u8d26\u53f7'.A1>, <セル u'126\u8d26\u53f7'.A2>, <セル u'126\u8d26\u53f7'.A3>), ( <セル u'126\u8d26\u53f7'.B1>, <セル u'126\u8d26\u53f7'.B2>, <セル u'126\u8d26\u53f7'.B3>), (<セル u'126\ u8d26\u53f7'.C1>, <セル u'126\u8d26\u53f7'.C2>, <セル u'126\u8d26\u53f7'.C3>), (<セル u'126\u8d26\u53f7'.D1) >, <セル u'126\u8d26\u53f7'.D2>, <セル u'126\u8d26\u53f7'.D3>), (<セル u'126\u8d26\u53f7'.E1>, <セル u' 126\u8d26\u53f7'.E2>, <セル u'126\u8d26\u53f7'.E3>), (<セル u'126\u8d26\u53f7'.F1>, <セル u'126\u8d26\u53f7' .F2>, <セル u'126\u8d26\u53f7'.F3>)]
特定の列 (2) を取得します: (<Cell u'126\u8d26\u53f7'.C1>, <Cell u'126\u8d26\u53f7'.C2>, <Cell u'126\u8d26\u53f7'.C3> )
获取某一行(1): (<Cell u'126\u8d26\u53f7'.A2>, <Cell u'126\u8d26\u53f7'.B2>, <Cell u'126\u8d26\u53f7'.C2>, <セル u'126\u8d26\u53f7'.D2>、<セル u'126\u8d26\u53f7'.E2>、<セル u'126\u8d26\u53f7'.F2>)
行番号と列番号 (2,2) のセルを取得します: <Cell u'126\u8d26\u53f7'.B2>
行番号と列番号のセルの内容を取得します (2,2) xiaxiaoxu1987
行番号と列番号の書き込み内容 (11,11): 'xiaxiaoxu' xiaxiaoxu
行番号と列番号が現在の日付 (13,13) に書き込まれます: 2018-07-10 21:28:14
プロセスは終了コード 0 で終了しました
これで Excel の操作がカプセル化されたので、メインプログラムでデータを読み込んでみましょう。
テストスクリプト.py:
#encoding=utf-8
#著者-夏暁徐
SeleniumインポートWebドライバーから
インポート時間
selenium.webdriver.support.ui から WebDriverWait をインポート
selenium.webdriver.common.by からインポート
selenium.common.Exceptions からインポート TimeoutException、NoSuchElementException
トレースバックをインポートする
PageObject.Login_Page インポートから *
PageObject.AddressBook インポートから *
Action.add_contact import から *
Action.login インポートから *
ProjectVar.var からインポート *
Util.Excel インポートから *
driver=webdriver.Firefox(executable_path='c:\\geckodriver')
driver.get('http://mail.126.com')
pe=parseExcel(test_data_excel_path)
pe.set_sheet_by_name(u"126 アカウント")
print pe.get_default_sheet()
rows=pe.get_all_rows()[1:]
enumerate(rows) の id、row の場合:
row[4].value =='y' の場合:
ユーザー名 = row[1].value
パスワード = row[2].value
ユーザー名、パスワードを印刷する
試す:
ログイン(ドライバー、ユーザー名、パスワード)
pe.set_sheet_by_name(u"連絡先")
print pe.get_default_sheet()
rows1=pe.get_all_rows()[1:]
print "行1:",行1
id1、enumerate(rows1) の行の場合:
row[7].value == 'y'の場合:
試す:
#print row[1].value,row[2].value,row[3].value,row[4].value,row[5].value
#print "実行1"
add_contact(ドライバー,row[1].value,row[2].value,row[3].value,row[4].value,row[5].value)
print "assert word:",row[6].value in driver.page_source
row[6].value を出力します
pe.write_cell_content(id1+2,10,"パス")
例外、e を除く:
print u"例外メッセージ:",e.message
pe.write_cell_content(id1+2,10,"失敗")
それ以外:
pe.write_cell_content(id1+2,10,u"忽略")
続く
例外、e を除く:
pe.set_sheet_by_name(u"126 アカウント")
print u"例外メッセージ:",e
pe.write_cell_content(id+2,5,"失敗")
それ以外:
pe.set_sheet_by_name(u"126 アカウント")
pe.write_cell_content(id+2,6,u"忽略")
続く
結果: 実行OK
C:\Python27\python.exe D:/test/dataDrivenTestPractice1/TestScript/TestScript.py
126アカウント
xiaxiaoxu1987 グローロード
連絡担当者
rows1: [(<セル u'\u8054\u7cfb\u4eba'.A2>, <セル u'\u8054\u7cfb\u4eba'.B2>, <セル u'\u8054\u7cfb\u4eba'.C2>, <セル u'\u8054\u7cfb\u4eba'.D2>、<セル u'\u8054\u7cfb\u4eba'.E2>、<セル u'\u8054\u7cfb\u4eba'.F2>、<セル u'\u8054 \u7cfb\u4eba'.G2>、<セル u'\u8054\u7cfb\u4eba'.H2>、<セル u'\u8054\u7cfb\u4eba'.I2>、<セル u'\u8054\u7cfb\u4eba' .J2>)、(<セル u'\u8054\u7cfb\u4eba'.A3>、<セル u'\u8054\u7cfb\u4eba'.B3>、<セル u'\u8054\u7cfb\u4eba'.C3> 、<セル u'\u8054\u7cfb\u4eba'.D3>、<セル u'\u8054\u7cfb\u4eba'.E3>、<セル u'\u8054\u7cfb\u4eba'.F3>、<セル u' \u8054\u7cfb\u4eba'.G3>、<セル u'\u8054\u7cfb\u4eba'.H3>、<セル u'\u8054\u7cfb\u4eba'.I3>, <セル u'\u8054\u7cfb\u4eba'.J3>), (<セル u'\u8054\u7cfb\u4eba'.A4>, <セル u'\u8054\u7cfb\u4eba'.J3>) '\u8054\u7cfb\u4eba'.B4>、<セル u'\u8054\u7cfb\u4eba'.C4>、<セル u'\u8054\u7cfb\u4eba'.D4>、<セル u'\u8054\u7cfb \u4eba'.E4>、<セル u'\u8054\u7cfb\u4eba'.F4>、<セル u'\u8054\u7cfb\u4eba'.G4>、<セル u'\u8054\u7cfb\u4eba'.H4 >, <セル u'\u8054\u7cfb\u4eba'.I4>, <セル u'\u8054\u7cfb\u4eba'.J4>), (<セル u'\u8054\u7cfb\u4eba'.A5>, <セル u'\u8054\u7cfb\u4eba'.B5>、<セル u'\u8054\u7cfb\u4eba'.C5>、<セル u'\u8054\u7cfb\u4eba'.D5>、<セル u'\u8054 \u7cfb\u4eba'.E5>、<セル u'\u8054\u7cfb\u4eba'.F5>、<セル u'\u8054\u7cfb\u4eba'.G5>、<セル u'\u8054\u7cfb\u4eba'.H5>、<セル u'\u8054\u7cfb\u4eba'.I5>、<セル u'\ u8054\u7cfb\u4eba'.J5>)]
アサートワード: True
アサートワード: True
ジョン・ドウ
プロセスは終了コード 0 で終了しました
Excel の結果:
この時点で、フレームワークのほとんどの機能がカプセル化されたので、次に、プログラムの実行時にログを出力できるようにログ モジュールを構築しましょう。
ステップ 12 - ログモジュールを追加する
Conf パッケージの下に新しい Logger.conf ログ構成ファイルを作成します。これにより、ロガー、プロセッサー、およびフォーマッタが構成されます。ログの具体的な詳細については、後ほど説明します。
#logger.conf
########################################### #
[ロガー]
key=root,example01,example02
[logger_root]
level=DEBUG
handlers=hand01,hand02
[logger_example01]
handlers=hand01,hand02
qualname=example01
propagate=0
[logger_example02]
handlers=hand01,hand03
qualname=example02
propagate=0
#############################################
[ハンドラー]
key=hand01,hand02,hand03
[handler_hand01]
class=StreamHandler
level=INFO
formatter=form01
args=(sys.stderr,)
[handler_hand02]
class=FileHandler
level=DEBUG
formatter=form01
args=('DataDrivenFrameWork.log', 'a')
[handler_hand03]
class=handlers.RotatingFileHandler
level=INFO
formatter=form01
args=('DataDrivenFrameWork.log', 'a', 10*1024*1024, 5 )
############################################
[フォーマッタ]
key=form01,form02
[formatter_form01]
format=%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s datefmt=%
Y-%m-%d %H:%M:%S
[formatter_form02]
format=%(name)-12s: %(levelname)-8s %(message)s
datefmt=%Y-%m-%d %H:%M:%S
Util パッケージの下に新しい log.py ファイルを作成して、ログ操作をカプセル化します。
ログ.py:
#encoding=utf-8
#著者-夏暁徐
インポートログ
インポートlogging.config
ProjectVar.var からインポート *
#ログ設定ファイルを読み取る
logging.config.fileConfig(プロジェクトパス+"\\Conf\\Logger.conf")
#ログ形式を選択します
logger=logging.getLogger("example02")
デフォルトエラー(メッセージ):
#デバッグレベル情報を出力する
logger.error(メッセージ)
デフォルト情報(メッセージ):
#情報レベル情報を印刷します
logger.info(メッセージ)
デフォルトの警告(メッセージ):
#警告レベル情報を出力する
logger.warning(メッセージ)
__name__=="__main__"の場合:
#テストコード
info("こんにちは")
print "設定ファイルのパス:",project_path+"\\Conf\\Logger.conf"
error("世界!")
warning("グローリーロード!")
結果: OK
C:\Python27\python.exe D:/test/dataDrivenTestPractice1/Util/log.py
2018-07-11 21:32:12 log.py[line:19] 情報 こんにちは。
設定ファイルのパス: D:\test\dataDrivenTestPractice1\Conf\Logger.conf
2018-07-11 21:32:12 log.py[line:15] エラーワールド!
2018-07-11 21:32:12 log.py[line:23] 警告グローロード!
プロセスは終了コード 0 で終了しました
ログのカプセル化が完了したので、メイン プログラムを変更してログを呼び出しましょう。
テストスクリプト.py:
#encoding=utf-8
#著者-夏暁徐
SeleniumインポートWebドライバーから
インポート時間
selenium.webdriver.support.ui から WebDriverWait をインポート
selenium.webdriver.common.by からインポート
selenium.common.Exceptions からインポート TimeoutException、NoSuchElementException
トレースバックをインポートする
PageObject.Login_Page インポートから *
PageObject.AddressBook インポートから *
Action.add_contact import から *
Action.login インポートから *
ProjectVar.var からインポート *
Util.Excel インポートから *
Util.log インポートから *
driver=webdriver.Firefox(executable_path='c:\\geckodriver')
driver.get('http://mail.126.com')
pe=parseExcel(test_data_excel_path)
pe.set_sheet_by_name(u"126 アカウント")
print pe.get_default_sheet()
rows=pe.get_all_rows()[1:]
enumerate(rows) の id、row の場合:
row[4].value =='y' の場合:
ユーザー名 = row[1].value
パスワード = row[2].value
ユーザー名、パスワードを印刷する
試す:
ログイン(ドライバー、ユーザー名、パスワード)
pe.set_sheet_by_name(u"連絡先")
print pe.get_default_sheet()
rows1=pe.get_all_rows()[1:]
print "行1:",行1
test_data_pass_flag=True#Result 表現。Excel 結果の最終書き込みに使用されます。
id1、enumerate(rows1) の行の場合:
row[7].value == 'y'の場合:
試す:
#print row[1].value,row[2].value,row[3].value,row[4].value,row[5].value
print "log0711",row[1],row[1].value
print "log0711",type(row[1].value)
#実際に連絡先を追加する操作を実行する
add_contact(ドライバー,row[1].value,row[2].value,row[3].value,row[4].value,row[5].value)
print "assert word:",row[6].value
driver.page_source の row[6].value をアサート
pe.write_cell_content(id1+2,10,"pass")#assert はエラーを報告せず、アサーションが成功したことを示します
例外、e を除く:
#print u"例外メッセージ 01",e.message
pe.write_cell_content(id1+2,10,"失敗")
test_data_pass_flag=False#コードはこの時点に到達し、例外が発生しテストが失敗したことを示します。
info(u"例外メッセージ01" + e.message) #ログを出力する
else:#説明識別子は「n」です、データを無視します
pe.write_cell_content(id1+2,10,u"忽略")
続く
if test_data_pass_flag ==True:#フラグが True の場合、結果は成功です
pe.set_sheet_by_name(u"126 アカウント")
pe.write_cell_content(id+2,5,"成功")
else:#フラグがFalseであることを示します
pe.set_sheet_by_name(u"126 アカウント")
pe.write_cell_content(id+2,5,"失敗")
例外、e を除く:
pe.set_sheet_by_name(u"126 アカウント")
#print u"例外メッセージ 02:",e
pe.write_cell_content(id+2,6,"失敗")
info(u"例外メッセージ02:"+e.message)#ログを出力する
タイムスリープ(2)
driver.quit()
else:#識別子が「n」であることを示すこの分岐を実行します
pe.set_sheet_by_name(u"126 アカウント")
pe.write_cell_content(id+2,6,u"忽略")
続く
結果: 実行OK
C:\Python27\python.exe D:/test/dataDrivenTestPractice1/TestScript/TestScript.py
126アカウント
xiaxiaoxu1987 グローロード
2018-07-11 22:55:25 log.py[line:19] INFO ログインに成功しました
連絡担当者
rows1: [(<セル u'\u8054\u7cfb\u4eba'.A2>, <セル u'\u8054\u7cfb\u4eba'.B2>, <セル u'\u8054\u7cfb\u4eba'.C2>, <セル u'\u8054\u7cfb\u4eba'.D2>、<セル u'\u8054\u7cfb\u4eba'.E2>、<セル u'\u8054\u7cfb\u4eba'.F2>、<セル u'\u8054 \u7cfb\u4eba'.G2>、<セル u'\u8054\u7cfb\u4eba'.H2>、<セル u'\u8054\u7cfb\u4eba'.I2>、<セル u'\u8054\u7cfb\u4eba' .J2>)、(<セル u'\u8054\u7cfb\u4eba'.A3>、<セル u'\u8054\u7cfb\u4eba'.B3>、<セル u'\u8054\u7cfb\u4eba'.C3> 、<セル u'\u8054\u7cfb\u4eba'.D3>、<セル u'\u8054\u7cfb\u4eba'.E3>、<セル u'\u8054\u7cfb\u4eba'.F3>、<セル u' \u8054\u7cfb\u4eba'.G3>、<セル u'\u8054\u7cfb\u4eba'.H3>、<セル u'\u8054\u7cfb\u4eba'.I3>, <セル u'\u8054\u7cfb\u4eba'.J3>), (<セル u'\u8054\u7cfb\u4eba'.A4>, <セル u'\u8054\u7cfb\u4eba'.J3>) '\u8054\u7cfb\u4eba'.B4>、<セル u'\u8054\u7cfb\u4eba'.C4>、<セル u'\u8054\u7cfb\u4eba'.D4>、<セル u'\u8054\u7cfb \u4eba'.E4>、<セル u'\u8054\u7cfb\u4eba'.F4>、<セル u'\u8054\u7cfb\u4eba'.G4>、<セル u'\u8054\u7cfb\u4eba'.H4 >, <セル u'\u8054\u7cfb\u4eba'.I4>, <セル u'\u8054\u7cfb\u4eba'.J4>), (<セル u'\u8054\u7cfb\u4eba'.A5>, <セル u'\u8054\u7cfb\u4eba'.B5>、<セル u'\u8054\u7cfb\u4eba'.C5>、<セル u'\u8054\u7cfb\u4eba'.D5>、<セル u'\u8054 \u7cfb\u4eba'.E5>、<セル u'\u8054\u7cfb\u4eba'.F5>、<セル u'\u8054\u7cfb\u4eba'.G5>、<セル u'\u8054\u7cfb\u4eba'.H5>、<セル u'\u8054\u7cfb\u4eba'.I5>、<セル u'\ u8054\u7cfb\u4eba'.J5>)]
log0711 <セル u'\u8054\u7cfb\u4eba'.B2> ユリ
log0711 <タイプ 'unicode'>
アサートワード: [email protected]
プロセスは終了コード 0 で終了しました
また、login.py ファイルは、ログイン アクションの実行後に、ログインの成功を示すログを作成することもできます。
この時点で、メイン プログラムは、データの読み取り、メールボックスへのログイン、連絡先の追加、およびテスト結果の Excel への書き込みを実装しました。基本的な機能は完了しました。次に、もう 1 つ作業を実行しましょう。これはほぼ完璧になります。時間のカプセル化。プログラム内で time 関数を呼び出して、指定された時間形式を書き込みます。
ステップ 13 - 共通の時間操作のカプセル化
Util パッケージの下に新しい FormatTime.py を作成します。
FormatTime.py
#encoding=utf-8
#著者-夏暁徐
#encoding=utf-8
インポート時間
from datetime import timedelta,date
def date_time_chinese():
print u"returns the current time string,format for YYYY年mm月dd日HH时MM分SS秒"
return time.strftime("%Y年 %m月 %d日 %H時 %M分 %S秒", time.localtime())
def date_chinese():
print u"YYYY年mm月dd日の形式で現在の時刻文字列を返します"
return time.strftime("%Y年%m月%d日",time.localtime())
def time_chinese():
print u"HH 時間 MM 分 SS 秒の形式で現在の時刻文字列を返します"
return time.strftime("%H 時 %M 分 %S 秒", time.localtime())
def date_time():
print "現在の時刻文字列を YYYY-mm-dd HH:MM:SS の形式で返します"
return time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())
def date_time_slash():
print "現在の時刻文字列を返します。形式は YYYY/mm/dd HH:MM:SS です"
return time.strftime("%Y/%m/%d %H:%M:%S",time.localtime())
デフォルトの日付():
print "現在の時刻文字列を YYYY-mm-dd の形式で返します"
return time.strftime("%Y-%m-%d",time.localtime())
def date_slash():
print "現在の時刻文字列を YYYY/mm/dd の形式で返します"
return time.strftime("%Y/%m/%d",time.localtime())
def 回():
print "現在の時刻文字列を HH:MM:SS 形式で返します"
return time.strftime("%H:%M:%S",time.localtime())
定義年():
print "現在の時刻文字列を年の形式で返します"
return time.strftime("%Y",time.localtime())
デフォルト月():
print "現在の時刻文字列を月の形式で返します"
return time.strftime("%m",time.localtime())
定義日():
print "現在の時刻文字列を日の形式で返します"
return time.strftime("%d",time.localtime())
デフォルト時間():
print "現在の時刻文字列を時間の形式で返します"
return time.strftime("%H",time.localtime())
def 分():
print "現在の時刻文字列を分の形式で返します"
return time.strftime("%M",time.localtime())
デフォルト秒():
print "現在の時刻文字列を返します。秒の形式を指定します"
return time.strftime("%S",time.localtime())
def str_to_tuple(stime):
print "文字列変数を時間タプルに返します"
return time.strptime(stime,"%Y-%m-%d %H:%M:%S")
def add_date(day_num):
今日=日付.今日()
print "現在の日付-%s と時間間隔-%s を返します" %(today,day_num)
回=今日+時間デルタ(日=day_num)
戻り時間
def sub_date(day_num):
今日=日付.今日()
print "現在の日付 - %s から 1 つの時間間隔 - %s を引いた値を返します" %(today,day_num)
回=今日の時間デルタ(日=day_num)
戻り時間
__name__=='__main__' の場合:
#テストコード
print date_time_chinese()
print date_chinese()
print time_chinese()
print date_time()
print date_time_slash()
日付を出力()
print date_slash()
印刷回数()
年を出力()
月を出力()
印刷日()
時間を表示()
分を出力()
秒数を表示()
time1=time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())
print str_to_tuple(time1)
print add_date(2)
サブ日付を印刷(2)
結果: OK、中国語を pycharm でトランスコードする必要はありませんが、メモ帳で実行するにはトランスコードが必要です。
C:\Python27\python.exe D:/test/dataDrivenTestPractice1/Util/FormatTime.py
YYYY 年 mm 月 dd 日 HH 時 MM 分 SS 秒の形式で現在の時刻文字列を返します。
2018年7月11日 23時01分36秒
returns the current time string, format for YYYY年mm月dd日
2018 年 7 月 11 日
現在の時刻文字列を返します。形式は HH 時 MM 分 SS 秒です。
23:01:36
YYYY-mm-dd HH:MM:SS の形式で現在の時刻文字列を返します。
2018-07-11 23:01:36
現在の時刻文字列、YYYY/mm/dd HH:MM:SS の形式を返します。
2018/07/11 23:01:36
現在の時刻文字列、YYYY-mm-dd の形式を返します
2018-07-11
現在の時刻文字列、YYYY/mm/dd の形式を返します。
2018/07/11
現在の時刻文字列を HH:MM:SS の形式で返します
23:01:36
現在の時刻文字列、年の形式を返します
2018年
現在の時刻文字列、月の形式を返します
07
現在の時刻文字列、日の形式を返します
11
現在の時刻文字列を時間の形式で返します
23
現在の時刻文字列、分の形式を返します
01
現在の時刻文字列を秒の形式で返します
36
文字列変数を時間タプルに返します
time.struct_time(tm_year=2018, tm_mon=7, tm_mday=11, tm_hour=23, tm_min=1, tm_sec=36, tm_wday=2, tm_yday=192, tm_isdst=-1)
現在の日付 2018-07-11 と時間間隔 2 を返します。
2018-07-13
現在の日付-2018-07-11 から 1 つの時間間隔を引いた値-2 を返します。
2018-07-09
プロセスは終了コード 0 で終了しました
メインプログラムを変更し、time 関数を呼び出し、時刻を出力します。
テストスクリプト.py:
#encoding=utf-8
#著者-夏暁徐
SeleniumインポートWebドライバーから
インポート時間
selenium.webdriver.support.ui から WebDriverWait をインポート
selenium.webdriver.common.by からインポート
selenium.common.Exceptions からインポート TimeoutException、NoSuchElementException
トレースバックをインポートする
PageObject.Login_Page インポートから *
PageObject.AddressBook インポートから *
Action.add_contact import から *
Action.login インポートから *
ProjectVar.var からインポート *
Util.Excel インポートから *
Util.log インポートから *
Util.FormatTime インポートから *
driver=webdriver.Firefox(executable_path='c:\\geckodriver')
driver.get('http://mail.126.com')
pe=parseExcel(test_data_excel_path)
pe.set_sheet_by_name(u"126 アカウント")
print pe.get_default_sheet()
rows=pe.get_all_rows()[1:]
enumerate(rows) の id、row の場合:
row[4].value =='y' の場合:
ユーザー名 = row[1].value
パスワード = row[2].value
ユーザー名、パスワードを印刷する
試す:
ログイン(ドライバー、ユーザー名、パスワード)
pe.set_sheet_by_name(u"連絡先")
print pe.get_default_sheet()
rows1=pe.get_all_rows()[1:]
print "行1:",行1
test_data_pass_flag=True#Result 表現。Excel 結果の最終書き込みに使用されます。
id1、enumerate(rows1) の行の場合:
row[7].value == 'y'の場合:
試す:
#print row[1].value,row[2].value,row[3].value,row[4].value,row[5].value
print "log0711",row[1],row[1].value
print "log0711",type(row[1].value)
#実際に連絡先を追加する操作を実行する
add_contact(ドライバー,row[1].value,row[2].value,row[3].value,row[4].value,row[5].value)
pe.write_cell_content(id1 + 2, 9, date_time())
print "assert word:",row[6].value
driver.page_source の row[6].value をアサート
pe.write_cell_content(id1+2,10,"pass")#assert はエラーを報告せず、アサーションが成功したことを示します
例外、e を除く:
#print u"例外メッセージ 01",e.message
pe.write_cell_content(id1+2,10,"失敗")
pe.write_cell_content(id1+2,9,date_time())
test_data_pass_flag=False#コードはこの時点に到達し、例外が発生しテストが失敗したことを示します。
info(u"例外メッセージ01" + e.message) #ログを出力する
else:#説明識別子は「n」です、データを無視します
pe.write_cell_content(id1+2,10,u"忽略")
pe.write_cell_content(id1 + 2, 9,date_time())
続く
if test_data_pass_flag ==True:#フラグが True の場合、結果は成功です
pe.set_sheet_by_name(u"126 アカウント")
pe.write_cell_content(id+2,6,"成功")
else:#フラグがFalseであることを示します
pe.set_sheet_by_name(u"126 アカウント")
pe.write_cell_content(id+2,6,"失敗")
例外、e を除く:
pe.set_sheet_by_name(u"126 アカウント")
#print u"例外メッセージ 02:",e
pe.write_cell_content(id+2,6,"失敗")
info(u"例外メッセージ02:"+e.message)#ログを出力する
タイムスリープ(2)
driver.quit()
else:#識別子が「n」であることを示すこの分岐を実行します
pe.set_sheet_by_name(u"126 アカウント")
pe.write_cell_content(id+2,6,u"忽略")
続く
結果: OK
C:\Python27\python.exe D:/test/dataDrivenTestPractice1/TestScript/TestScript.py
126アカウント
xiaxiaoxu1987 グローロード
2018-07-11 23:17:39 log.py[line:19] INFO ログインに成功しました
連絡担当者
rows1: [(<セル u'\u8054\u7cfb\u4eba'.A2>, <セル u'\u8054\u7cfb\u4eba'.B2>, <セル u'\u8054\u7cfb\u4eba'.C2>, <セル u'\u8054\u7cfb\u4eba'.D2>、<セル u'\u8054\u7cfb\u4eba'.E2>、<セル u'\u8054\u7cfb\u4eba'.F2>、<セル u'\u8054 \u7cfb\u4eba'.G2>、<セル u'\u8054\u7cfb\u4eba'.H2>、<セル u'\u8054\u7cfb\u4eba'.I2>、<セル u'\u8054\u7cfb\u4eba' .J2>)、(<セル u'\u8054\u7cfb\u4eba'.A3>、<セル u'\u8054\u7cfb\u4eba'.B3>、<セル u'\u8054\u7cfb\u4eba'.C3> 、<セル u'\u8054\u7cfb\u4eba'.D3>、<セル u'\u8054\u7cfb\u4eba'.E3>、<セル u'\u8054\u7cfb\u4eba'.F3>、<セル u' \u8054\u7cfb\u4eba'.G3>、<セル u'\u8054\u7cfb\u4eba'.H3>、<セル u'\u8054\u7cfb\u4eba'.I3>, <セル u'\u8054\u7cfb\u4eba'.J3>), (<セル u'\u8054\u7cfb\u4eba'.A4>, <セル u'\u8054\u7cfb\u4eba'.J3>) '\u8054\u7cfb\u4eba'.B4>、<セル u'\u8054\u7cfb\u4eba'.C4>、<セル u'\u8054\u7cfb\u4eba'.D4>、<セル u'\u8054\u7cfb \u4eba'.E4>、<セル u'\u8054\u7cfb\u4eba'.F4>、<セル u'\u8054\u7cfb\u4eba'.G4>、<セル u'\u8054\u7cfb\u4eba'.H4 >, <セル u'\u8054\u7cfb\u4eba'.I4>, <セル u'\u8054\u7cfb\u4eba'.J4>), (<セル u'\u8054\u7cfb\u4eba'.A5>, <セル u'\u8054\u7cfb\u4eba'.B5>、<セル u'\u8054\u7cfb\u4eba'.C5>、<セル u'\u8054\u7cfb\u4eba'.D5>、<セル u'\u8054 \u7cfb\u4eba'.E5>、<セル u'\u8054\u7cfb\u4eba'.F5>、<セル u'\u8054\u7cfb\u4eba'.G5>、<セル u'\u8054\u7cfb\u4eba'.H5>、<セル u'\u8054\u7cfb\u4eba'.I5>、<セル u'\ u8054\u7cfb\u4eba'.J5>)]
log0711 <セル u'\u8054\u7cfb\u4eba'.B2> ユリ
log0711 <タイプ 'unicode'>
YYYY-mm-dd HH:MM:SS の形式で現在の時刻文字列を返します。
アサートワード: [email protected]
YYYY-mm-dd HH:MM:SS の形式で現在の時刻文字列を返します。
YYYY-mm-dd HH:MM:SS の形式で現在の時刻文字列を返します。
YYYY-mm-dd HH:MM:SS の形式で現在の時刻文字列を返します。
プロセスは終了コード 0 で終了しました
Excel は結果を書き込みます。
要約:
ここでは、まず分散した関数を組み立ててより大きな関数を実装し、次にその大きな関数をより大きな関数に編成しています。最終的に、メイン プログラムに表示されるのは、独立した大きな関数の組み合わせです。可読性が高く、保守も簡単です。
このように、フレームワーク全体を、ばらばらのコードの羅列から関数のカプセル化へと変換し、データとプログラムを分離し、ある独立した機能をカプセル化して統合することで、フレームワークを構築する手順に慣れてきます。いくつかの大きなブロックにカプセル化することの詳細と利点を理解した後、後でテスト フレームワークを構築するときに、これらの大きなブロックに従うだけでよく、このアイデアとロジックとその必要性を受け入れるのが比較的簡単になります。このようなテスト フレームワークを構築する必要がある理由と、このテスト フレームワークの原則を理解し、推論を導き、他のタイプのテスト フレームワークに拡張します。
もっと実践的な練習をしましょう~
データ駆動型フレームワークの構造は次のとおりです。
データ駆動型フレームワークの構造:
アクション:
ログインや連絡先の追加などの操作要素のカプセル化された機能。。。
conf:
ログ設定ファイル
ポジショニング要素設定ファイル
データベース設定ファイル
PageObject:
ページはクラスであり、クラスのメソッドはページ上の関連要素を取得できます
ProjectVar:
プロジェクトのパス プロジェクト
関連のグローバル変数
TestData: (ファイルまたは Excel)
テストケース
テスト データ
TestScript:
テスト フレームワークを実行するメイン プログラム: 入り口。主にテスト データ ファイルを読み取り
、テスト結果を記録します。
ユーティリティ ツール クラス
関数:
構成ファイルを読み取る
Excel ツール クラス
タイム クラス
要素を見つけるメソッド
位置決め要素を読み取るメソッド 構成ファイル
ログ メソッド
ログ操作の
スクリーン
ショット レポート テンプレート
フレームワークのソースコードが必要な場合は、コメントエリアに電子メールを残してください~
最後に、私が蓄積した真実のドキュメントと学習資料を皆さんに共有します。必要に応じて、それらを手に取ってください。上記のコンテンツは、ソフトウェア テストを行う友人にとって、最も包括的で完全な準備倉庫となるはずです
。各モジュールについては、インターネット上の質の高いブログ投稿やプロジェクトも多数参照し、知識のポイントを逃さないように努めました。多くの友人がこれらのコンテンツを参考にして検討し、BATJ などの大手メーカーからオファーを獲得しました。ソフトウェア テストの学習者として、これがあなたにも役立つことを願っています。
以下の WeChat 公式アカウントをフォローして無料で入手してください! ↓ ↓ ↓ ↓ ↓