2023,8种必备Selenium编写自动化用例的技巧(建议收藏)

news2024/10/7 15:14:53

在开始自动化时,您可能会遇到各种可能包含在自动化代码中的方法,技术,框架和工具。有时,与提供更好的灵活性或解决问题的更好方法相比,这种多功能性导致代码更加复杂。在编写自动化代码时,重要的是我们能够清楚地描述自动化测试的目标以及我们如何实现它。

话虽如此,编写“干净的代码”以提供更好的可维护性和可读性很重要。编写干净的代码也不是一件容易的事,您需要牢记许多最佳实践。以下主题突出显示了编写更好的自动化代码应获得的8条银线。

1.命名约定

当我们从手动转向自动化或实际上以任何编程语言编写代码时,这确实是要牢记的经验法则之一。遵循正确的命名约定有助于更轻松地理解代码和维护。此命名约定暗含变量,方法,类和包。例如,您的方法名称应特定于其用途。“ Register_User()”方法描述了在该方法中显示用户注册的方法。明确定义的方法名称增加了脚本的易于维护和可读性。这同样适用于变量命名。我注意到许多人提到变量为a,b,c等,甚至将Web元素称为Weblelement1,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("sadhvi.singh@navyuginfo.com");
        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("sadhvi.singh@navyuginfo.com");
        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.减少,重用和回收

确保将您的方法分解到用户场景的最小块上非常重要。它们应涵盖简单和单一的流程。不要让您的方法与单一方法涵盖的多个功能过于复杂。例如,登录功能需要在应用程序上注册用户。将您的注册功能保留在另一个方法中,如果需要,请在登录方法中调用该方法。降低方法的复杂度可简化代码的可维护性。

另外,在需要的地方重复使用您的方法,请勿将相同的代码复制粘贴到不同的方法中。这导致代码中不必要的重复和冗余。增加代码行并不意味着您已经编写了不错的代码。重构和优化代码是编写稳定,健壮和更好的自动化代码的关键。

回收也是编写更好的自动化代码的另一个有用技巧。我有经验丰富的人员可以自动化遗留系统,不倾向于在自动化框架中更改现有方法,而不会在现有功能发生变化时重写另一种方法。这只是使框架变得脆弱。每当流程改变时,总是要更新现有方法,尽管它有其自身的挑战,即新用户可能不知道该方法可能具有的依赖性,但是我认为我们应该始终以长远的眼光来看待问题,而不是实现那些较短的目标。 。

下面是一个示例,说明如何将登录代码简化为一小部分功能,并使用了另一种注册方法来简化整个过程。

@Test
    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("sadhvi.singh@navyuginfo.com");
        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();
    }   

    @Test
    public void Login_User()
    {

          driver.get("https://accounts.lambdatest.com/login");
          driver.findElement(By.xpath("//input[@name='email']")).sendKeys("User2@gmail.com");
          driver.findElement(By.xpath("//input[@name='password']")).sendKeys("TestUser123");
          driver.findElement(By.xpath("//button[@class='sign-up-btn']")).click();

    }

    @AfterClass
    public static void BrowserClose()
    {

        driver.quit();
    }

    }

3.合理地组织测试

好的,这确实是确保更好的自动化代码的主要可操作见解之一。它不仅易于理解,而且在维护上无需花费太多精力。从长远来看,借助框架来构建测试可以增加工作价值,并减少维护工作。您可以通过使用由JUnit和TestNG之类的框架提供的注释来控制应用程序的流程。例如,使用@BeforeClass之类的注释可以帮助您指导耗时的活动,例如连接到数据库,设置浏览器等与此方法相关的代码以及与此相关联的@BeforeClass注释。这可以帮助自动化测试仪立即知道该方法的确切功能以及何时调用该方法。试想一下,您的设置过程很清楚,并且已从代码的其他部分中整理出来。

下面的示例突出显示了通过TestNG框架展示了一种更好的结构化方法:

import static org.junit.Assert.*;

import java.util.concurrent.TimeUnit;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

public class Lamdatest {

    static WebDriver driver;

    @BeforeClass
    public static void BrowserOpen()
    {
        System.setProperty("webdriver.chrome.driver", "chromepath"); 
        driver= new ChromeDriver() ;
        driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
    }

    @Test(priority=1)
    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("sadhvi.singh@navyuginfo.com");
        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();
        String url= driver.getCurrentUrl();
        assertEquals("fail- unable to register", url, "https://accounts.lambdatest.com/user/email-verification");

    }   

    @Test(dependsOnMethods="Register_User") 
    public void Login_User()
    {

          driver.get("https://accounts.lambdatest.com/login");
          driver.findElement(By.xpath("//input[@name='email']")).sendKeys("User2@gmail.com");
          driver.findElement(By.xpath("//input[@name='password']")).sendKeys("TestUser123");
          driver.findElement(By.xpath("//button[@class='sign-up-btn']")).click();

    }

    @AfterClass
    public static void BrowserClose()
    {

        driver.quit();
    }

    }

确定哪些注释应该与哪种测试方法相关联是很重要的。通过明确的依赖关系和优先级,可以根据应用程序的流程来构造测试和代码。

4.全面验证您的测试

作为质量检查人员,您要做的就是验证您的预期和实际满足情况,这与您的自动化代码相同。如果您的脚本不符合验证要求,那么创建一个脚本将毫无意义,也没有任何意义。理想情况下,每个用户操作都应该像测试用例步骤一样进行验证,无论它是在验证元素的可见性,还是要记住版式提示,文本表示形式,页面重定向或任何形式的视觉验证,甚至是关于评估数据库的结果。

即使您的验证无法确定,也会显示失败消息,以便您可以找出问题所在。我们在验证代码方面犯的最大错误是从确保验证通过的角度编写。我们从未考虑过如果代码失败或未达到预期效果会发生什么,那么继续下去将需要什么。

如果您希望在验证失败后立即中断测试并跳至另一测试,则可以使用硬断言,而如果您希望在同一页面上验证多个检查,则可以选择软断言。决定完全使用哪个断言取决于用例。

以下是在登录页面上执行的断言示例。在此方法中,将创建一种方法,其中使用有效凭据登录用户,然后使用另一种方法确保用户不会使用无效凭据登录并显示错误消息。

//validate user able to login with valid credentials
        @Test
        public void Login_User() throws IOException
        {

            driver.get("https://accounts.lambdatest.com/login");
            driver.findElement(By.xpath("//input[@name='email']")).sendKeys("User2@gmail.com");
            driver.findElement(By.xpath("//input[@name='password']")).sendKeys("TetsUser123");
            driver.findElement(By.xpath("//button[@class='sign-up-btn']")).click();
              WebDriverWait wait= new WebDriverWait(driver, 15);
              wait.until(ExpectedConditions.visibilityOf(driver.findElement(By.xpath("//a[@class='user-profile dropdown-toggle']"))));
              String Current_url= driver.getCurrentUrl();
              Assert.assertEquals("https://accounts.lambdatest.com/user/email-verification", Current_url);
              System.out.println("user logged in sucesfully");
              driver.findElement(By.xpath("//a[@class='user-profile dropdown-toggle']")).click();
              driver.findElement(By.xpath("//a[contains(text(),'Logout')]")).click();
            }

        //validate user is unable to login with invalid credentials
                @Test
                public void Login_invalid_User() throws IOException
                {

                      driver.get("https://accounts.lambdatest.com/login");
                      driver.findElement(By.xpath("//input[@name='email']")).sendKeys("User21@gmail.com");
                      driver.findElement(By.xpath("//input[@name='password']")).sendKeys("TestUser123");
                      driver.findElement(By.xpath("//button[@class='sign-up-btn']")).click();
                      WebDriverWait wait= new WebDriverWait(driver, 15);
                      String str= driver.findElement(By.xpath("//p[@class='error-mass']")).getText();
                      String Current_url= driver.getCurrentUrl();
                      Assert.assertEquals("https://accounts.lambdatest.com/login", Current_url);
                      System.out.println(str);
                }

覆盖多个验证检查的方法可能有所不同,或者您可以像我上面所做的那样为每个验证选择不同的方法,或者可以选择在try-catch块下的单个方法中进行所有验证。

5.sleep不能改善稳定性

我们倾向于相信的最大神话,尤其是当我们刚接触自动化领域时,是通过为脚本提供足够的等待量,必要或不必要的等待会导致脚本顺利执行。相反,它使脚本不稳定,并增加了总体执行时间。这种静态睡眠的主要问题是,我们不了解运行测试的机器的负载,因此可能导致超时。因此,应避免使用thread.sleep来维护更好的自动化代码。对脚本使用等待的一种更好的方法是通过条件绑定,其中脚本可以像人类一样等待直到满足特定条件。例如,等待直到某个元素可见或不可见。

作为开发更好的自动化代码的一种选择,显式和流畅的等待更加适应。

6.进行测试,数据驱动

在对多种形式的数据进行测试时,测试变得更加有效,当编写更好的自动化代码以测试Web应用程序或任何其他软件时,测试也是如此。在自动化中,关键是通过多种形式的数据测试测试代码,而不是为每个数据编写不同的测试脚本。这可以通过数据驱动的测试框架轻松实现。它有助于将测试数据输入存储到外部数据库中,例如CSV文件,excel文件,文本文件,XML文件甚至是ODBC存储库。此数据被调用到脚本中,并一次又一次地运行在相同的测试代码中。与手动工作相比,这有助于减少冗余并加快执行速度。发现新的bug。这种方法的另一个好处是,它减少了您可能必须添加的测试脚本的数量,从而加快了测试周期。

与之保持同步,它还有助于简化脚本的可维护性。如果应用程序发生任何更改,代码中的所有硬编码值都可能会中断。实现此目的的一种更简单的方法是将所有硬编码组件设置为变量驱动。例如,通过将它们各自的值存储在excel工作表中并在脚本中调用它们,可以使所有定位器都不受代码限制。万一您的任何定位器损坏了,您只需要在excel中更改定位器的值即可,而根本不需要触摸脚本。

数据驱动测试的一个基本示例是:

        public void Login_User() throws IOException
        {

            File f1= new File("C://Users//navyug//Desktop//Test.xlsx");
            FileInputStream scr= new FileInputStream(f1);
            XSSFWorkbook book= new XSSFWorkbook(scr);
            XSSFSheet sheet=book.getSheetAt(0);
            for(int i=0; i<=sheet.getLastRowNum(); i++ )
            {
                //XSSFCell cell= sheet.getRow(i).getCell(1);
             Row row = sheet.getRow(i);
             Cell cell = row.getCell(0);

              driver.findElement(By.xpath("//input[@name='email']")).sendKeys(cell.toString());
              cell= row.getCell(1);

              driver.findElement(By.xpath("//input[@name='password']")).sendKeys(cell.toString());

            driver.findElement(By.xpath("//button[@class='sign-up-btn']")).click();
              WebDriverWait wait= new WebDriverWait(driver, 15);
              wait.until(ExpectedConditions.visibilityOf(driver.findElement(By.xpath("//a[@class='user-profile dropdown-toggle']"))));
              String Current_url= driver.getCurrentUrl();
              Assert.assertEquals("https://accounts.lambdatest.com/user/email-verification", Current_url);
              System.out.println("user logged in sucesfully");
              takescreenshot();
              driver.findElement(By.xpath("//a[@class='user-profile dropdown-toggle']")).click();
              driver.findElement(By.xpath("//a[contains(text(),'Logout')]")).click();
            }
        }

上面的代码显示了从Excel获取的用于不同登录凭据的数据。对于Xpath也可以扩展同样的功能,其中XPath值也可以从excel中提取。在这里,通过数据驱动方法解决的关键点是从我们的代码中删除硬编码的值,使其成为面向变量,并使其在多组输入中运行同一段代码。

7.不要错过报告!

如果自动化代码没有向您报告结果,则该代码将无法正常工作。为了优化您作为自动化工程师的工作,重要的是要知道哪些测试代码通过了,哪些失败并附带了屏幕截图。您可以向利益相关者展示的最佳投资回报是通过报告。共享这些详细的报告可提供可见性,并减少您验证测试执行脚本的时间。您可以通过TestNG HTML报告生成,JUnit报告生成等各种技术来实现报告,也可以使用扩展库来实现报告。

下面的代码显示了一个示例,其中登录功能的完成后已截取了屏幕截图作为验证通过的证明,而下面是执行后生成的TestNG报告的示例:

//validate user able to login with valid credentials
        @Test
        public void Login_User() throws IOException
        {

            driver.get("https://accounts.lambdatest.com/login");
            driver.findElement(By.xpath("//input[@name='email']")).sendKeys("User2@gmail.com");
            driver.findElement(By.xpath("//input[@name='password']")).sendKeys("TetsUser123");
            driver.findElement(By.xpath("//button[@class='sign-up-btn']")).click();
              WebDriverWait wait= new WebDriverWait(driver, 15);
              wait.until(ExpectedConditions.visibilityOf(driver.findElement(By.xpath("//a[@class='user-profile dropdown-toggle']"))));
              String Current_url= driver.getCurrentUrl();
              Assert.assertEquals("https://accounts.lambdatest.com/user/email-verification", Current_url);
              System.out.println("user logged in sucesfully");
              takescreenshot();
              driver.findElement(By.xpath("//a[@class='user-profile dropdown-toggle']")).click();
              driver.findElement(By.xpath("//a[contains(text(),'Logout')]")).click();
            }

        public void takescreenshot() throws IOException
        {
            TakesScreenshot scr= ((TakesScreenshot)driver);
            File file1= scr.getScreenshotAs(OutputType.FILE);

           FileUtils.copyFile(file1, new File("C:\\Users\\navyug\\Desktop\\Login_user.PNG")); 
        }

8.不要忘记跨浏览器测试!

如今,所有Web应用程序都支持多种浏览器和版本。重要的是,您的代码应针对多个浏览器,而不是针对特定的浏览器。在特定的浏览器上运行代码会失去应用程序的跨浏览器兼容性。执行跨浏览器测试,以确保您的应用程序在所有主要浏览器上都能提供无缝的用户体验,我们可以扩展此测试的自动化范围。诸如TestNG之类的框架有助于轻松地在各种浏览器中执行测试。

下面的代码显示了如何通过TestNG在多个浏览器上运行自动化代码

public class crowssbrowser {

    static WebDriver driver;

    @Parameters("browser")
    @BeforeClass
    public static void Browser_Select(String browser)
    {
        if(browser.equalsIgnoreCase("firefox")) {

            System.setProperty("webdriver.firefox.marionette", "geckodriverpath");
              driver = new FirefoxDriver();

          // If browser is IE, then do this   

          }else if (browser.equalsIgnoreCase("chrome")) { 

              // Here I am setting up the path for my IEDriver

              System.setProperty("webdriver.chrome.driver", "chromedriverpath"); 
                driver= new ChromeDriver() ;
          }

        driver.get("https://accounts.lambdatest.com/login");
          driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
    }

XML代码: 

<?xml ve
rsion="1.0" encoding="UTF-8"?>

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">

<suite name="Suite" parallel="none">

 <test name="FirefoxTest">

 <parameter name="browser" value="firefox" />

 <classes>

 <class name="crowssbrowser" />

 </classes>

 </test>

 <test name="chrometest">

 <parameter name="browser" value="chrome" />

 <classes>

 <class name="crowssbrowser" />

 </classes>

 </test>

</suite>

上面的代码显示了一种以浏览器为参数的方法,其中设置了不同的浏览器驱动程序。使用TestNG XML文件,我们已将参数传递为不同的浏览器,在这些浏览器上将运行用于Firefox和chrome上的登录功能的代码。以上内容就是本篇的全部内容以上内容希望对你有帮助,有被帮助到的朋友欢迎点赞,评论。

END绵薄之力

最后感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!

加入我的软件测试交流群:110685036免费获取~(同行大佬一起学术交流,每晚都有大佬直播分享技术知识点)

软件测试面试小程序

被百万人刷爆的软件测试题库!!!谁用谁知道!!!全网最全面试刷题小程序,手机就可以刷题,地铁上公交上,卷起来!

涵盖以下这些面试题板块:

1、软件测试基础理论 ,2、web,app,接口功能测试 ,3、网络 ,4、数据库 ,5、linux

6、web,app,接口自动化 ,7、性能测试 ,8、编程基础,9、hr面试题 ,10、开放性测试题,11、安全测试,12、计算机基础

获取方式 :

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/529439.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Jangow

Jangow 1.环境准备 靶场地址&#xff1a;https://www.vulnhub.com/entry/jangow-101,754/下载好靶机之后直接使用VMware Workstation Pro虚拟机导入环境&#xff0c;启动即可&#xff0c;将网段设置为NAT模式攻击机&#xff1a;kali&#xff08;192.168.80.180&#xff09;靶…

【电厂用 多功能数码显示 HJY-F931B/D交流三相电压继电器JOSEF约瑟】

用途 HJY系列数字式交流电压继电器为瞬时动作特性&#xff0c;用于发电机&#xff0c;变压器&#xff0c;输电线路的继电保护装 置中作为过压或欠压的闭锁启动元件。 安装结构 导轨安装9&#xff0c;导轨安装E两种结构方式&#xff0c;具体尺寸请参考外型尺寸图。特点 (1). 采…

局域网内使用的多人协同编辑文档的软件哪个好?对比5款主流平台

支持局域网内多人协同编辑文档的软件或平台哪个好&#xff1f;PingCode 、Confluence 等知识库工具和腾讯文档、飞书文档等都支持多人协作编辑&#xff0c;怎么选&#xff1f;这是企业团队在找文档管理工具最常见的问题。 支持局域网内协同编辑的软件可以分为两个大类&#xf…

azkaban介绍

目录 为什么需要工作流调度系统 什么是azkaban azkaban适用场景 azkaban特点 常见的工作流调度系统 azkaban和Ooize特性对比 azkaban的架构 azkaban调度的任务有可能有那些类型 总结 为什么需要工作流调度系统 一个完整的大数据分析系统&#xff0c;必然由很多任务单…

基于显扬科技3D视觉相机的医疗试管分拣系统

行业现状&#xff1a; 医疗试管分拣是医疗行业中的一个重要环节&#xff0c;指将医疗实验室或生物技术研究中的试管按照一定的规则进行分拣&#xff0c;并对试管的类型、位置、数量等信息进行识别和管理。 随着医疗技术的不断发展和诊断治疗的精细化&#xff0c;医疗试管分拣…

Python之selenium关于Chrome驱动位置和闪退的问题

目录 一、Chromedriver放置的位置二、浏览器闪退 一、Chromedriver放置的位置 背景&#xff1a;之前由于Chrome浏览器自动升级后&#xff0c;导致驱动与浏览器不匹配&#xff0c;自己也不知道问题出在哪儿&#xff0c;花费了我大量时间去排查&#xff0c;所以接下来记录一些。…

Linux ps -A 和 ps -ef

Linux ps &#xff08;英文全拼&#xff1a;process status&#xff09;命令用于显示当前进程的状态&#xff0c;类似于 windows 的任务管理器 ps -A | grep xx 显示xx所有的进程 ps -ef | grep xx 显示xx在一个终端的所有进程 注意这里ef 其实可以拆开理解 e 是显示所有进…

oracle报错ORA-12514

问题&#xff1a;oracle使用服务名orcl登录不成功&#xff0c;并且报错 ORA-12514, TNS:listener does not currently know of service requested in conn原因分析&#xff1a; ORA-12514 错误通常表示 Oracle 数据库监听器无法识别客户端请求的服务名称。这可能是由于以下原因…

什么是ERP、APS和MES

01 先来说说ERP与MES的区别 ERP&#xff1a;企业资源计划 一天中午&#xff0c;丈夫在外给家里打电话&#xff1a;“亲爱的老婆&#xff0c;晚上想带几个同事回家吃饭可以吗&#xff1f;”&#xff08;订货意向&#xff09; 丈夫&#xff1a;“6个人&#xff0c;我们7点左右回…

【计算机视觉】如何利用 CLIP 做简单的人脸任务?(含源代码)

文章目录 一、数据集介绍二、源代码 结果三、代码逐行解读 一、数据集介绍 CELEBA 数据集&#xff08;CelebFaces Attributes Dataset&#xff09;是一个大规模的人脸图像数据集&#xff0c;旨在用于训练和评估人脸相关的计算机视觉模型。该数据集由众多名人的脸部图像组成&a…

【MySQL】MySQL索引--聚簇索引和非聚簇索引的区别

文章目录 前言1.聚簇索引和非聚簇索引的概念2.两者详细介绍2.1 聚簇索引2.2 非聚簇索引 3. 两者的区别3.1 数据存储方式3.2 二级索引查询 前言 1.聚簇索引和非聚簇索引的概念 数据库表的索引从数据存储方式上可以分为聚簇索引和非聚簇索引两种。“聚簇”的意思是数据行被按照…

【Java|golang】1072. 按列翻转得到最大值等行数

给定 m x n 矩阵 matrix 。 你可以从中选出任意数量的列并翻转其上的 每个 单元格。&#xff08;即翻转后&#xff0c;单元格的值从 0 变成 1&#xff0c;或者从 1 变为 0 。&#xff09; 返回 经过一些翻转后&#xff0c;行与行之间所有值都相等的最大行数 。 示例 1&#…

使用TensorFlow构建,绘制和解释人工神经网络

使用 Python 进行深度学习&#xff1a;神经网络&#xff08;完整教程&#xff09; 使用TensorFlow构建&#xff0c;绘制和解释人工神经网络 总结 在本文中&#xff0c;我将展示如何使用Python构建神经网络&#xff0c;以及如何使用可视化和创建模型预测解释器向业务解释深度学习…

【PCIE】pcie设备协议分析和crash后定位

分析RP Headerlog在协议中位置 能力集寄存器协议字段 HeaderLog字段偏移以及各字段含义 headerLog和协议的对应入截图中内容 completer id就是完成的ID&#xff0c;对应的BDF &#xff0c;如下图 b5:00.0 AECap寄存器 其中 first error pointer 含义&#xff1a; 这里有专…

对于 Git 每一次提交的时间信息,什么是作者日期和提交者日期

文章目录 什么是作者日期和提交者日期如何查看作者日期和提交者日期方法 1方法 2方法 3 修改最近一次提交的时间 什么是作者日期和提交者日期 对于 Git 的每一次提交&#xff0c;在 TortoiseGit 和 IntelliJ IDEA 都可以看到这次提交的时间。但很多人不知道的是&#xff0c;Gi…

人脸识别2:Python实现人脸识别Face Recognition(含源码)

人脸识别2&#xff1a;Python实现人脸识别Face Recognition(含源码) 目录 人脸识别2&#xff1a;Python实现人脸识别Face Recognition(含源码) 1. 前言 2. 项目安装 3. 人脸识别系统 &#xff08;1&#xff09;人脸检测和关键点检测 &#xff08;2&#xff09;人脸校准 …

【数据结构与算法】布隆(Bloom Filter)过滤器

文章目录 1、什么是布隆过滤器2、布隆过滤器的使用场景3、布隆过滤器的原理3.1 数据结构3.2 空间计算3.3 增加元素3.4 查询元素3.5 修改元素3.6 删除元素 4、Redis集成布隆过滤器4.1 版本要求4.2 安装&编译4.2.1 下载插件压缩包4.2.2 解压4.2.3 编译插件 4.3 Redis集成4.3.…

《硅谷钢铁侠:埃隆·马斯克的冒险人生》成就21世纪的史诗

《硅谷钢铁侠&#xff1a;埃隆马斯克的冒险人生》成就21世纪的史诗 阿什利万斯&#xff08;Ashlee Vance&#xff09;&#xff1a;美国商业专栏作家、资深科技记者。 文章目录 《硅谷钢铁侠&#xff1a;埃隆马斯克的冒险人生》成就21世纪的史诗马斯克的超级公司摘录感悟梦 马斯…

免费SSL:阿里云SSL证书免费申请入口及流程开启HTTPS

阿里云SSL免费证书在哪申请&#xff1f;一个阿里云账号一年可以申请20张免费SSL证书&#xff0c;很多同学找不到免费SSL的入口&#xff0c;阿小云来详细说下阿里云SSL证书免费申请入口链接以及免费SSL证书申请流程&#xff0c;有同学反馈阿里云免费SSL证书没有了&#xff1f;错…

【Python共享文件】——Python快速搭建HTTP web服务实现文件共享并公网远程访问

文章目录 1. 前言2. 视频教程3. 本地文件服务器搭建3.1 python的安装和设置3.2 cpolar的安装和注册 4. 本地文件服务器的发布4.1 Cpolar云端设置4.2 Cpolar本地设置 5. 公网访问测试6. 结语 1. 前言 数据共享作为和连接作为互联网的基础应用&#xff0c;不仅在商业和办公场景有…