質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

デバッグ

デバッグはプログラムのバグや欠陥を検知し、開発中のバグを取り除く為のプロセスを指します。

テスト駆動開発

テスト駆動開発は、 プログラム開発手法の一種で、 プログラムに必要な各機能をテストとして書き、 そのテストが動作する必要最低限な実装を行い コードを洗練させる、といったサイクルを繰り返す手法の事です。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

selenium

Selenium(セレニウム)は、ブラウザをプログラムで作動させるフレームワークです。この原理を使うことにより、ブラウザのユーザーテストなどを自動化にすることができます。

Q&A

解決済

3回答

3602閲覧

selenium 引数でセレクタなどを選択したい!!

ryan06

総合スコア1

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

デバッグ

デバッグはプログラムのバグや欠陥を検知し、開発中のバグを取り除く為のプロセスを指します。

テスト駆動開発

テスト駆動開発は、 プログラム開発手法の一種で、 プログラムに必要な各機能をテストとして書き、 そのテストが動作する必要最低限な実装を行い コードを洗練させる、といったサイクルを繰り返す手法の事です。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

selenium

Selenium(セレニウム)は、ブラウザをプログラムで作動させるフレームワークです。この原理を使うことにより、ブラウザのユーザーテストなどを自動化にすることができます。

0グッド

0クリップ

投稿2020/09/10 15:09

前提・実現したいこと

ここに質問の内容を詳しく書いてください。
プログラミングを学び始めて間もないので見苦しい点が多々あると思いますがどうかお許しください。
現在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ページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答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
shirai

総合スコア1290

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ryan06

2020/09/13 11:24

ご回答ありがとうございます。 現在テストを行おうとしているアプリでは複数ページに渡り大量のフォームに値を入力、操作が必要で 被らない様に要素の取得にId、xpathを多用しています。(idが振られていないものも多) Seleniumリファレンスの関数をほとんど使うことになるので少しでも記述量が少なくなればと上記の様なことを試みました。 やはり一つ一つセレクタごとに関数を作るのが無難でしょうか?
shirai

2020/09/13 13:18

追記しました
guest

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
Supernove

総合スコア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

t_obara

総合スコア5488

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問