自動化を始めるとき、自動化コードに含めることができるさまざまな方法、テクニック、フレームワーク、ツールに遭遇するかもしれません。場合によっては、この多用途性により、より優れた柔軟性や問題解決方法が提供されるよりも、コードがより複雑になることがあります。自動化コードを作成するときは、自動化テストの目標とその目標をどのように達成するかを明確に説明できることが重要です。そうは言っても、保守性と読みやすさを向上させるためには、「クリーンなコード」を書くことが重要です。きれいなコードを書くことも簡単な作業ではないため、多くのベスト プラクティスを念頭に置く必要があります。次のトピックでは、より優れた自動化コードを作成するために獲得する必要がある 8 つの銀の糸に焦点を当てます。
1. 命名規則
これは、手動から自動に移行するとき、または実際にプログラミング言語でコーディングするときに覚えておくべき経験則の 1 つです。適切な命名規則に従うと、コードの理解と保守が容易になります。この命名規則は、変数、メソッド、クラス、パッケージを意味します。たとえば、メソッド名はその目的に応じたものにする必要があります。「Register_User()」メソッドには、このメソッドでのユーザー登録の表示方法が記述されています。メソッド名を明確に定義すると、メンテナンスが容易になり、スクリプトが読みやすくなります。変数の名前付けにも同じことが当てはまります。多くの人が変数を a、b、c などと呼んだり、Web 要素を Weblement1、Webelement2 などと呼んだりしていることに気づきました。この方法では、ユーザーには変数名が期待どおりに表示されません。
次に、命名エラーを示す例を示します。
public void Register_User() throws InterruptedException
{
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
driver.get("https://www.lambdatest.com/ ");
driver.manage().window().maximize();
WebElement web1= driver.findElement(By.xpath("//a[text()='Free Sign Up']"));
web1.click();
WebElement web2=driver.findElement(By.xpath("//input[@name='organization']"));
web2.sendKeys("LambdaTest");
WebElement web3=driver.findElement(By.xpath("//input[@name='first_name']"));
web3.sendKeys("Test");
WebElement web4=driver.findElement(By.xpath("//input[@name='last_name']"));
web4.sendKeys("User");
WebElement web5=driver.findElement(By.xpath("//input[@name='email']"));
web5.sendKeys("[email protected]");
WebElement web6=driver.findElement(By.xpath("//input[@name='password']"));
web6.sendKeys("TestUser123");
WebElement web7=driver.findElement(By.xpath("//input[@name='phone']"));
web7.sendKeys("9412262090");
WebElement web8=driver.findElement(By.xpath("//button[text()='SIGN UP']"));
web8.click();
Thread.sleep(3500);
}
上記のコードは、「method1」がメソッドが正確に何をするのかについてユーザーに手がかりを与えていないことを示しています。さらに、すべての Web 要素は web1、web2 などで表されます。ユーザーは、どの Web 要素がどのフィールドをキャプチャするかを特定できません。
上記の同じコードの場合、正しい表現は次のようにマークできます。
public void Register_User() throws InterruptedException
{
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
driver.get("https://www.lambdatest.com/ ");
driver.manage().window().maximize();
WebElement link= driver.findElement(By.xpath("//a[text()='Free Sign Up']"));
link.click();
WebElement organization=driver.findElement(By.xpath("//input[@name='organization']"));
organization.sendKeys("LambdaTest");
WebElement first_name=driver.findElement(By.xpath("//input[@name='first_name']"));
first_name.sendKeys("Test");
WebElement last_name=driver.findElement(By.xpath("//input[@name='last_name']"));
last_name.sendKeys("User");
WebElement email=driver.findElement(By.xpath("//input[@name='email']"));
email.sendKeys("[email protected]");
WebElement password=driver.findElement(By.xpath("//input[@name='password']"));
password.sendKeys("TestUser123");
WebElement phone_number=driver.findElement(By.xpath("//input[@name='phone']"));
phone_number.sendKeys("9412262090");
WebElement button=driver.findElement(By.xpath("//button[text()='SIGN UP']"));
button.click();
Thread.sleep(3500);
String url= driver.getCurrentUrl();
assertEquals("fail- unable to register", url, "https://accounts.lambdatest.com/user/email-verification");
}
ここで、メソッド名「Register_User」はユーザーを名前で明確に定義しており、メソッドにユーザー登録に関連するコードが含まれていることを示しています。同様に、すべての Web 要素または変数には、インテントの定義に使用されるキャプチャ フィールドに関連付けられた名前があります。
一般に、メソッドや変数を文書化するにはキャメル ケースが推奨されます。これは、読みやすさとスクリプトの保守の点で明確であるためです。
2. リデュース、リユース、リサイクル
メソッドをユーザー シナリオの最小の部分に分割することが重要です。単純で単一のプロセスをカバーする必要があります。単一のメソッドで複数の機能をカバーすることでアプローチを複雑にしすぎないでください。たとえば、ログイン機能を使用するには、ユーザーがアプリケーションに登録されている必要があります。登録機能を別のメソッドに保持し、必要に応じてログイン メソッドでそのメソッドを呼び出します。メソッドの複雑さを軽減すると、コードの保守性が簡素化されます。
また、必要に応じてメソッドを再利用し、同じコードをコピーして別のメソッドに貼り付けないでください。これにより、コードに不必要な重複と冗長性が生じます。コード行を追加しても、適切なコードを作成したことにはなりません。コードのリファクタリングと最適化は、安定した堅牢な、より優れた自動化コードを作成するための鍵です。
リサイクルも、より優れた自動化コードを作成するためのもう 1 つの便利なテクニックです。レガシー システムを自動化した経験を持つ人々の中には、既存の機能が変更されたときに、別のメソッドを書き直さずに自動化フレームワーク内の既存のメソッドを変更する傾向がない人もいます。これではフレームワークが脆弱になるだけです。プロセスが変更されるたびに既存のメソッドを常に更新します。ただし、新しいユーザーがメソッドの依存関係に気づかない可能性があるという独自の課題もありますが、それらの短い目標を達成するのではなく、常に長期的な視点を持つ必要があると思います。。
ここでは、ログイン コードを小さな機能に減らし、別のサインアップ方法を使用してプロセス全体を簡素化する方法の例を示します。
1@Test
2 public void Register_User() throws InterruptedException
3 {
4 driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
5 driver.get("https://www.lambdatest.com/ ");
6 driver.manage().window().maximize();
7 WebElement link= driver.findElement(By.xpath("//a[text()='Free Sign Up']"));
8 link.click();
9 WebElement organization=driver.findElement(By.xpath("//input[@name='organization']"));
10 organization.sendKeys("LambdaTest");
11 WebElement first_name=driver.findElement(By.xpath("//input[@name='first_name']"));
12 first_name.sendKeys("Test");
13 WebElement last_name=driver.findElement(By.xpath("//input[@name='last_name']"));
14 last_name.sendKeys("User");
15 WebElement email=driver.findElement(By.xpath("//input[@name='email']"));
16 email.sendKeys("[email protected]");
17 WebElement password=driver.findElement(By.xpath("//input[@name='password']"));
18 password.sendKeys("TestUser123");
19 WebElement phone_number=driver.findElement(By.xpath("//input[@name='phone']"));
20 phone_number.sendKeys("9412262090");
21 WebElement button=driver.findElement(By.xpath("//button[text()='SIGN UP']"));
22 button.click();
23 }
24
25 @Test
26 public void Login_User()
27 {
28
29 driver.get("https://accounts.lambdatest.com/login");
30 driver.findElement(By.xpath("//input[@name='email']")).sendKeys("[email protected]");
31 driver.findElement(By.xpath("//input[@name='password']")).sendKeys("TestUser123");
32 driver.findElement(By.xpath("//button[@class='sign-up-btn']")).click();
33
34 }
35
36 @AfterClass
37 public static void BrowserClose()
38 {
39
40 driver.quit();
41 }
42
43
44 }
3. テストを適切に整理する
確かに、これは、より優れた自動化コードを確保するための主要な実用的な洞察の 1 つです。理解しやすいだけでなく、維持するための労力もほとんどかかりません。長期的には、フレームワークを利用してテストを構築すると価値が高まり、メンテナンスの労力が軽減されます。JUnit や TestNG などのフレームワークによって提供されるアノテーションを使用して、アプリケーションのフローを制御できます。たとえば、@BeforeClass のようなアノテーションを使用すると、データベースへの接続、ブラウザのセットアップなど、このメソッドとこれに関連付けられた @BeforeClass アノテーションに関連するコードなどの時間のかかるアクティビティをガイドするのに役立ちます。これにより、自動テスターはメソッドが正確に何を行うのか、いつ呼び出されるのかをすぐに知ることができます。想像してみてください。セットアップ プロセスは明確であり、コードの他の部分から分類されています。
以下の例は、TestNG フレームワークを使用した、より構造化されたアプローチを強調しています。
1import static org.junit.Assert.*;
2
3import java.util.concurrent.TimeUnit;
4
5import org.openqa.selenium.By;
6import org.openqa.selenium.WebDriver;
7import org.openqa.selenium.WebElement;
8import org.openqa.selenium.chrome.ChromeDriver;
9import org.testng.annotations.AfterClass;
10import org.testng.annotations.BeforeClass;
11import org.testng.annotations.Test;
12
13public class Lamdatest {
14
15 static WebDriver driver;
16
17 @BeforeClass
18 public static void BrowserOpen()
19 {
20 System.setProperty("webdriver.chrome.driver", "chromepath");
21 driver= new ChromeDriver() ;
22 driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
23 }
24
25 @Test(priority=1)
26 public void Register_User() throws InterruptedException
27 {
28 driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
29 driver.get("https://www.lambdatest.com/ ");
30 driver.manage().window().maximize();
31 WebElement link= driver.findElement(By.xpath("//a[text()='Free Sign Up']"));
32 link.click();
33 WebElement organization=driver.findElement(By.xpath("//input[@name='organization']"));
34 organization.sendKeys("LambdaTest");
35 WebElement first_name=driver.findElement(By.xpath("//input[@name='first_name']"));
36 first_name.sendKeys("Test");
37 WebElement last_name=driver.findElement(By.xpath("//input[@name='last_name']"));
38 last_name.sendKeys("User");
39 WebElement email=driver.findElement(By.xpath("//input[@name='email']"));
40 email.sendKeys("[email protected]");
41 WebElement password=driver.findElement(By.xpath("//input[@name='password']"));
42 password.sendKeys("TestUser123");
43 WebElement phone_number=driver.findElement(By.xpath("//input[@name='phone']"));
44 phone_number.sendKeys("9412262090");
45 WebElement button=driver.findElement(By.xpath("//button[text()='SIGN UP']"));
46 button.click();
47 String url= driver.getCurrentUrl();
48 assertEquals("fail- unable to register", url, "https://accounts.lambdatest.com/user/email-verification");
49
50 }
51
52 @Test(dependsOnMethods="Register_User")
53 public void Login_User()
54 {
55
56 driver.get("https://accounts.lambdatest.com/login");
57 driver.findElement(By.xpath("//input[@name='email']")).sendKeys("[email protected]");
58 driver.findElement(By.xpath("//input[@name='password']")).sendKeys("TestUser123");
59 driver.findElement(By.xpath("//button[@class='sign-up-btn']")).click();
60
61 }
62
63
64
65 @AfterClass
66 public static void BrowserClose()
67 {
68
69 driver.quit();
70 }
71
72
73 }
どのアノテーションをどのテストメソッドに関連付けるかを決定することが重要です。明確な依存関係と優先順位により、テストとコードをアプリケーションのフローに従って構造化できます。
4. テストを徹底的に検証する
QA として行う必要があるのは、期待と実際の実現が自動化コードと同じであることを確認することだけです。スクリプトが検証要件を満たしていない場合、スクリプトを作成する意味がありません。理想的には、すべてのユーザー アクションは、要素の可視性の検証、活版印刷のヒントの記憶、テキスト表現、ページ リダイレクト、またはあらゆる形式の視覚的検証であっても、データベースの結果の評価であっても、テスト ケースのステップのように検証される必要があります。
検証が決定的でない場合でも、問題を特定できるように失敗メッセージが表示されます。検証コードで犯す最大の間違いは、検証に合格することを確認するという観点からコードを作成することです。コードが失敗した場合、または期待どおりに動作しなかった場合に何が起こるか、続行するには何が必要になるかなど、まったく考えていませんでした。
検証が失敗したらすぐにテストを中断して別のテストにジャンプする場合はハード アサートを使用でき、同じページで複数のチェックを検証する場合はソフト アサートを選択できます。どのアサートを使用するかを正確に決定するのは、ユースケースによって異なります。
以下は、ログイン ページで実行されるアサーションの例です。このメソッドでは、ユーザーが有効な資格情報でログインするメソッドを作成し、別のメソッドを使用して、ユーザーが無効な資格情報でログインしてエラー メッセージを表示しないようにします。
1//validate user able to login with valid credentials
2 @Test
3 public void Login_User() throws IOException
4 {
5
6 driver.get("https://accounts.lambdatest.com/login");
7 driver.findElement(By.xpath("//input[@name='email']")).sendKeys("[email protected]");
8 driver.findElement(By.xpath("//input[@name='password']")).sendKeys("TetsUser123");
9 driver.findElement(By.xpath("//button[@class='sign-up-btn']")).click();
10 WebDriverWait wait= new WebDriverWait(driver, 15);
11 wait.until(ExpectedConditions.visibilityOf(driver.findElement(By.xpath("//a[@class='user-profile dropdown-toggle']"))));
12 String Current_url= driver.getCurrentUrl();
13 Assert.assertEquals("https://accounts.lambdatest.com/user/email-verification", Current_url);
14 System.out.println("user logged in sucesfully");
15 driver.findElement(By.xpath("//a[@class='user-profile dropdown-toggle']")).click();
16 driver.findElement(By.xpath("//a[contains(text(),'Logout')]")).click();
17 }
18
19
20
21 //validate user is unable to login with invalid credentials
22 @Test
23 public void Login_invalid_User() throws IOException
24 {
25
26 driver.get("https://accounts.lambdatest.com/login");
27 driver.findElement(By.xpath("//input[@name='email']")).sendKeys("[email protected]");
28 driver.findElement(By.xpath("//input[@name='password']")).sendKeys("TestUser123");
29 driver.findElement(By.xpath("//button[@class='sign-up-btn']")).click();
30 WebDriverWait wait= new WebDriverWait(driver, 15);
31 String str= driver.findElement(By.xpath("//p[@class='error-mass']")).getText();
32 String Current_url= driver.getCurrentUrl();
33 Assert.assertEquals("https://accounts.lambdatest.com/login", Current_url);
34 System.out.println(str);
35 }
複数の検証チェックをオーバーライドする方法はさまざまで、上で行ったように検証ごとに異なる方法を選択することも、try-catch ブロックの下で単一のメソッドですべての検証を実行することも選択できます。
5.睡眠は安定性を向上させません
特に自動化の世界に慣れていない場合に信じがちな最大の誤解は、スクリプトに十分な待機を与えることで、必要な待機または不必要な待機がスムーズなスクリプトの実行につながるということです。むしろ、スクリプトが不安定になり、全体的な実行時間が長くなります。この種の静的スリープの主な問題は、テストを実行しているマシンの負荷がわからないため、タイムアウトが発生する可能性があることです。したがって、より優れた自動コードを維持するには、thread.sleep を回避する必要があります。スクリプトで待機を使用するより良い方法は、条件付きバインドを使用することです。これにより、スクリプトは特定の条件が満たされるまで人間のように待機できます。たとえば、要素が表示されるか非表示になるまで待機します。
明示的かつ流暢な待機は、より優れた自動化コードを開発するためのオプションとして、より適応性が高くなります。
6. テストを受けて、データ主導で
複数の形式のデータに対してテストする場合、テストはより効果的になります。また、Web アプリケーションやその他のソフトウェアをテストするための、より優れた自動コードを作成する場合もテストは効果的になります。自動化において重要なのは、データごとに異なるテスト スクリプトを作成するのではなく、複数の形式のデータを通じてテスト コードをテストすることです。これは、データ駆動型のテスト フレームワークを使用すると簡単に実現できます。CSV ファイル、Excel ファイル、テキスト ファイル、XML ファイル、さらには ODBC リポジトリなどの外部データベースにテスト データ入力を保存するのに役立ちます。このデータはスクリプトに呼び出され、同じテスト コードを繰り返し実行されます。これにより、手動作業に比べて冗長性が軽減され、実行が高速化されます。新しいバグを発見します。このアプローチのもう 1 つの利点は、追加する必要があるテスト スクリプトの数が減り、テスト サイクルが短縮されることです。
同期を保つことで、スクリプトの保守性も容易になります。アプリケーションに変更が発生すると、コード内のハードコーディングされた値が壊れる可能性があります。これを実現する簡単な方法は、すべてのハードコードされたコンポーネントを変数駆動にすることです。たとえば、それぞれの値を Excel シートに保存し、スクリプトで呼び出すことで、すべてのロケーターをコード不要にすることができます。ロケーターのいずれかが壊れている場合は、スクリプトには一切触れずに Excel でロケーターの値を変更するだけで済みます。
データ駆動型テストの基本的な例は次のとおりです。
1 public void Login_User() throws IOException
2 {
3
4 File f1= new File("C://Users//navyug//Desktop//Test.xlsx");
5 FileInputStream scr= new FileInputStream(f1);
6 XSSFWorkbook book= new XSSFWorkbook(scr);
7 XSSFSheet sheet=book.getSheetAt(0);
8 for(int i=0; i<=sheet.getLastRowNum(); i++ )
9 {
10 //XSSFCell cell= sheet.getRow(i).getCell(1);
11 Row row = sheet.getRow(i);
12 Cell cell = row.getCell(0);
13
14 driver.findElement(By.xpath("//input[@name='email']")).sendKeys(cell.toString());
15 cell= row.getCell(1);
16
17 driver.findElement(By.xpath("//input[@name='password']")).sendKeys(cell.toString());
18
19
20 driver.findElement(By.xpath("//button[@class='sign-up-btn']")).click();
21 WebDriverWait wait= new WebDriverWait(driver, 15);
22 wait.until(ExpectedConditions.visibilityOf(driver.findElement(By.xpath("//a[@class='user-profile dropdown-toggle']"))));
23 String Current_url= driver.getCurrentUrl();
24 Assert.assertEquals("https://accounts.lambdatest.com/user/email-verification", Current_url);
25 System.out.println("user logged in sucesfully");
26 takescreenshot();
27 driver.findElement(By.xpath("//a[@class='user-profile dropdown-toggle']")).click();
28 driver.findElement(By.xpath("//a[contains(text(),'Logout')]")).click();
29 }
30 }
上記のコードは、さまざまなログイン資格情報に対して Excel からフェッチされたデータを示しています。同じ機能を XPath に対して拡張することもでき、XPath 値を Excel から抽出することもできます。ここで、データ駆動型のアプローチによって解決される重要な点は、コードからハードコーディングされた値を削除し、変数指向にし、複数の入力セットで同じコードを実行できるようにすることです。
7. レポートをお見逃しなく!
自動コードが結果を報告しない場合、コードは機能しません。自動化エンジニアとしての作業を最適化するには、どのテスト コードが合格し、どのテスト コードが失敗したかをスクリーンショットを添付して把握することが重要です。ステークホルダーに示すことができる最良の ROI は、レポートを通じて提供されます。これらの詳細レポートを共有すると、可視性が向上し、テスト実行スクリプトの検証に費やす時間が短縮されます。TestNG HTML レポート生成、JUnit レポート生成などのさまざまなテクノロジを通じてレポートを実装したり、拡張ライブラリを使用してレポートを実装したりできます。
以下のコードは、ログイン機能の完了後に検証の証拠としてスクリーンショットが取得された例を示しています。また、以下は、実行後に生成された TestNG レポートの例です。
1//validate user able to login with valid credentials
2 @Test
3 public void Login_User() throws IOException
4 {
5
6 driver.get("https://accounts.lambdatest.com/login");
7 driver.findElement(By.xpath("//input[@name='email']")).sendKeys("[email protected]");
8 driver.findElement(By.xpath("//input[@name='password']")).sendKeys("TetsUser123");
9 driver.findElement(By.xpath("//button[@class='sign-up-btn']")).click();
10 WebDriverWait wait= new WebDriverWait(driver, 15);
11 wait.until(ExpectedConditions.visibilityOf(driver.findElement(By.xpath("//a[@class='user-profile dropdown-toggle']"))));
12 String Current_url= driver.getCurrentUrl();
13 Assert.assertEquals("https://accounts.lambdatest.com/user/email-verification", Current_url);
14 System.out.println("user logged in sucesfully");
15 takescreenshot();
16 driver.findElement(By.xpath("//a[@class='user-profile dropdown-toggle']")).click();
17 driver.findElement(By.xpath("//a[contains(text(),'Logout')]")).click();
18 }
19
20 public void takescreenshot() throws IOException
21 {
22 TakesScreenshot scr= ((TakesScreenshot)driver);
23 File file1= scr.getScreenshotAs(OutputType.FILE);
24
25 FileUtils.copyFile(file1, new File("C:\\Users\\navyug\\Desktop\\Login_user.PNG"));
26 }
8. クロスブラウザテストを忘れないでください。
最近のすべての Web アプリケーションは、複数のブラウザーとバージョンをサポートしています。タグは特定のブラウザではなく、複数のブラウザをターゲットにすることが重要です。特定のブラウザでコードを実行すると、アプリケーションのブラウザ間の互換性が失われます。クロスブラウザー テストを実行して、アプリケーションがすべての主要なブラウザーでシームレスなユーザー エクスペリエンスを提供できることを確認します。このテストの自動化の範囲を拡張できます。TestNG のようなフレームワークは、さまざまなブラウザでテストを簡単に実行するのに役立ちます。
以下のコードは、TestNG を介して複数のブラウザーで自動化コードを実行する方法を示しています。
1public class crowssbrowser {
2
3 static WebDriver driver;
4
5
6 @Parameters("browser")
7 @BeforeClass
8 public static void Browser_Select(String browser)
9 {
10 if(browser.equalsIgnoreCase("firefox")) {
11
12 System.setProperty("webdriver.firefox.marionette", "geckodriverpath");
13 driver = new FirefoxDriver();
14
16
17 }else if (browser.equalsIgnoreCase("chrome")) {
18
20
21 System.setProperty("webdriver.chrome.driver", "chromedriverpath");
22 driver= new ChromeDriver() ;
23 }
24
25 driver.get("https://accounts.lambdatest.com/login");
26 driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
27 }
XMLコード:
1<?xml ve
2rsion="1.0" encoding="UTF-8"?>
3
4<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
5
6<suite name="Suite" parallel="none">
7
8 <test name="FirefoxTest">
9
10 <parameter name="browser" value="firefox" />
11
12 <classes>
13
14 <class name="crowssbrowser" />
15
16 </classes>
17
18 </test>
19
20 <test name="chrometest">
21
22 <parameter name="browser" value="chrome" />
23
24 <classes>
25
26 <class name="crowssbrowser" />
27
28 </classes>
29
30 </test>
31
32</suite>
上記のコードは、ブラウザを引数として受け取るメソッドを示しており、さまざまなブラウザ ドライバが設定されています。TestNG XML ファイルを使用して、Firefox と chrome のログイン機能のコードが実行されるさまざまなブラウザーにパラメーターを渡しました。
最後に、私の記事を注意深く読んでくださった皆さんに感謝します。互恵性は常に必要です。それはそれほど価値のあるものではありませんが、必要な場合はそれを取り上げることができます。
これらの資料は、[ソフトウェア テスト] の友人にとって、最も包括的かつ完全な準備倉庫となるはずです。この倉庫は、最も困難な旅を乗り越える何万人ものテスト エンジニアにも同行してきました。お役に立てれば幸いです。パートナーは下の小さなカードをクリックしてください。受け取る