前提・実現したいこと
ここに質問の内容を詳しく書いてください。
プログラミングを学び始めて間もないので見苦しい点が多々あると思いますがどうかお許しください。
現在seleniumを使ってアプリケーションのテストを行うことになりました。
関数をまとめておくtest.pyを作り複数のファイルから関数を呼び出したいと思っています。
ただ、セレクタの数だけ関数を作成するのは面倒だと思い、下記のような関数を書きましたがうまくいきません。
どこか間違ってますでしょうか?
そもそも無理なことなのでしょうか?
下記以外にも色々な書き方を試してみましたが自分ではうまくいきませんでした。
どなたかご教授していただけると幸いです。
該当のソースコード
python
1test.py 2 3from selenium import webdriver 4 5driver = webdriver.Chrome("D:\chromedriver") 6driver.get("https://www.google.co.jp") 7#検索テキストボックスの要素をId属性名から取得 8 9 10def send_keys_text(SELECTER, VALUE, TEXT) 11 element = driver.find_element_by_SELECTER(VALUE) 12 element.send_keys(TEXT) 13 14def send_keys(SELECTER, VALUE, KEY) 15 element = driver.find_element_by_SELECTER(VALUE) 16 element.send_keys(Keys.KEY) 17
python
1page01.py 2 3import test 4 5def page01_test: 6 test.send_keys_text(’id’, ’realbox’, ‘テスト’) 7 8 test.send_keys(’id’, ’realbox’, ‘CONTROL,"a"’) 9 test.send_keys(’id’, ’realbox’, ‘DELETE’)
補足情報
プログラミング超初心者、selenium超超初心者の小心者なので、優しく教えていただけるとたすかります。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答3件
0
ベストアンサー
大きく間違っていることが2つあります。
1
find_element_by_SELECTER
とありますが、このような関数は存在しません。
SELECTER
という引数を持ってくることによって、
find_element_by_idを実現したいなのだと思いますが、
これは固定の関数名であり、引数を与えるということ自体ができないです。
メタプログラミングをすれば別かもしれませんが。。。
2
python
1from selenium import webdriver 2 3driver = webdriver.Chrome("D:\chromedriver") 4driver.get("https://www.google.co.jp")
をファイル内にクラスも関数も定義せずにそのまま書いていますが、
これではimport test
を実行した瞬間に、
driver
という変数が行方不明になってしまいます。
それからこの程度の関数でしたらわざわざ共通化する必要性を感じられません。
以下とりあえず動きそうなものあげますが、
先にドットインストールやUdemy等で
学習をしてからでないと、まともに目的を果たすのは難しいと思います。
python
1# test.py 2 3from selenium import webdriver 4from selenium.webdriver.common.keys import Keys 5 6SELECTOR_KEYS = {'id': '#', 'class': '.'} # この実装は拡張性が乏しく微妙です 7 8class selenium_base(object): 9 def __init__(self): 10 self.driver = webdriver.Chrome("D:\chromedriver") 11 self.driver.get("https://www.google.co.jp") 12 13 def send_keys_text(self, SELECTER, VALUE, TEXT) 14 self.driver.find_element_by_css_selector(SELECTOR_KEYS.get(SELECTER) + VALUE).send_keys(TEXT) 15 16 def send_keys(self, SELECTER, VALUE, *KEYS) 17 self.driver.find_element_by_css_selector(SELECTOR_KEYS.get(SELECTER) + VALUE).send_keys(eval('Keys.' + KEYS[0]) if len(KEYS[0]) == 1 else eval('Keys.' + KEYS[0] + ', ' + KEYS[1]))
python
1# page01.py 2 3import test 4 5def page01_test: 6 selenium_instance = test.selenium_base() 7 selenium_instance.send_keys_text('id', 'realbox', 'テスト') 8 selenium_instance.send_keys('id', 'realbox', 'CONTROL', 'a') 9 selenium_instance.send_keys('id', 'realbox', 'DELETE') 10 11page01_test
ついでに言うとgoogleはスクレイピング禁止です。
規約で明記されていますのでご注意を。
コメントを受けて追記
だとしたらそもそも分け方が間違っています。
page毎に関数を作り、テスト毎に値だけ渡してやるべきです。
下記例は
- pege01で色々とフォームを入力し、バリデーションが正しいとpage02に遷移する。
- page02で色々とフォームを入力し、バリデーションが正しいとpage03に遷移する。
という想定で作ってみました。
python
1# test.py 2 3from selenium import webdriver 4from selenium.webdriver.common.keys import Keys 5from selenium.webdriver.support.select import Select 6 7class selenium_base(object): 8 def __init__(self): 9 self.driver = webdriver.Chrome("D:\chromedriver") 10 self.driver.get("page01の入力ページ") 11 12 def page01(self, text1, text2, radio1, radio2, pulldown1, pulldown2): 13 hoge1 = '/html/body/div/div[1]/pre/em[1]' 14 hoge2 = '/html/body/div/div[18]' # hoge6まで適切なxpathを書いておく 15 16 self.driver.find_element_by_xpath(hoge1).send_keys(text1) 17 self.driver.find_element_by_xpath(hoge2).send_keys(text2) 18 self.driver.find_elements_by_xpath(hoge3)[radio1].click() 19 self.driver.find_elements_by_xpath(hoge4)[radio2].click() 20 Select(self.driver.find_element_by_xpath(hoge5)).select_by_visible_text(pulldown1) 21 Select(self.driver.find_element_by_xpath(hoge6)).select_by_visible_text(pulldown2) 22 self.driver.find_element_by_class_name('btn-primary').click() # 最後に送信ボタンを押す 23 24 def page02(self, text1, text2, radios): 25 hoge1 = '/html/body/div/div[1]/pre/em[1]' 26 hoge2 = '/html/body/div/div[18]' 27 hoge3 = '/html/body/div/div[19]/p' 28 29 self.driver.find_element_by_xpath(hoge1).send_keys(text1) 30 self.driver.find_element_by_xpath(hoge2).send_keys(text2) 31 for radio in radios: 32 self.driver.find_elements_by_xpath(hoge3)[radio].click() 33 self.driver.find_element_by_class_name('btn-primary').click() # 最後に送信ボタンを押す
python
1# test_case.py 2 3import test 4 5# 正常に最終ページまで遷移するテスト 6def success_test: 7 selenium_instance = test.selenium_base() 8 try: 9 selenium_instance.page01('あああ', 'いいい', 1, 3, 'ううう', 'えええ') 10 if selenium_instance.title != 'page02のタイトル': 11 print('正常なケースを試したはずですが、page01からpage02に遷移できませんでした。') 12 selenium_instance.quit() 13 return 14 selenium_instance.page02('あああ', 'いいい', [2, 3, 6, 7]) 15 if selenium_instance.title != 'page03のタイトル': 16 print('正常なケースを試したはずですが、page02からpage03に遷移できませんでした。') 17 else: 18 print('正常にpage03まで遷移できました。') 19 catch: 20 print('success_test中にエラーが発生しました。') 21 finally: 22 selenium_instance.quit() 23 print('success_testを終了します。') 24 25# page01からpage02への遷移で失敗するテスト 26def error_test1: 27 selenium_instance = test.selenium_base() 28 try: 29 # text1は10文字以上だとエラーが出るシステムだとする 30 selenium_instance.page01('あああああああああああああああ', 'いいい', 1, 3, 'ううう', 'えええ') 31 if selenium_instance.title == 'page02のタイトル': 32 print('異常なケースを試したはずですが、page01からpage02に遷移できてしまいました。') 33 else: 34 print('想定通りpage01でエラーが発生し先に進めませんでした。') 35 catch: 36 print('error_test1中にエラーが発生しました。') 37 finally: 38 selenium_instance.quit() 39 print('error_test1を終了します。') 40 41# page02からpage03への遷移で失敗するテスト 42def error_test2: 43 selenium_instance = test.selenium_base() 44 try: 45 selenium_instance.page01('あああ', 'いいい', 1, 3, 'ううう', 'えええ') 46 if selenium_instance.title != 'page02のタイトル': 47 print('正常なケースを試したはずですが、page01からpage02に遷移できませんでした。') 48 selenium_instance.quit() 49 return 50 # ラジオボタンの選択肢は5つ以下しか選べないシステムだとする 51 selenium_instance.page02('あああ', 'いいい', [2, 3, 6, 7, 10, 11]) 52 if selenium_instance.title == 'page03のタイトル': 53 print('異常なケースを試したはずですが、page02からpage03に遷移できてしまいました。') 54 else: 55 print('想定通りpage02でエラーが発生し先に進めませんでした。') 56 catch: 57 print('error_test2中にエラーが発生しました。') 58 finally: 59 selenium_instance.quit() 60 print('error_test2を終了します。') 61 62success_test 63error_test1 64error_test2
pytestの書き方ではないですが必要だったら適宜やってみてください。
投稿2020/09/10 16:48
編集2020/09/13 13:19総合スコア1290
0
まず、test.pyで関数を定義するときにコロン(:)をつけ忘れています。pythonで関数にコロンを忘れるとエラーになります。
あと、page01.py内で文字列を囲むときのクオーテーション(')もおかしいです。ちゃんと半角入力の状態でコロンを正しく打たないとエラーになります。
プログラム書くときはメモ帳アプリとかでなく、VS Codeなどのテキストエディタをちゃんと用意して、プログラムをかけば上記のミスが減ると思いますので、使うことをおすすめします。
プログラミング初心者であればいきなりseleniumuを使わずにこちらのサイトで勉強されてはいかがでしょうか。すべて無料で自分もこのサイトでPythonのプログラミングの基礎を勉強しました。
Python入門
そして、seleniumの方ですが、find_element_by_SELECTER
というメソッドは存在しません。
一度、find_element
系のメソッドがまとまっている記事があるので、ここを参考にするといいと思います。
Pythonで、Seleniumのfind_element系メソッドとPageObjectsを試してみた
そもそもseleniumはHTMLを理解していたほうがプログラムを書きやすいのでHTMLについても多少は勉強しましょう。
投稿2020/09/10 16:11
編集2020/09/10 16:14総合スコア1154
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
提示したソースで何をしたいのかよく読み取れませんが、
CSSセレクターを指定して要素を取得するメソッドはすでにありますが、こちらは利用できないのですか?
https://www.seleniumqref.com/api/python/element_get/Python_find_element_by_css_selector.html
find_element
でも良いと思います。
投稿2020/09/10 15:52
総合スコア5488
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/09/13 11:24
2020/09/13 13:18