2023年,8种必备Selenium编写自动化用例的技巧

news2024/10/6 12:20:21

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

话虽如此,编写“干净的代码”以提供更好的可维护性和可读性很重要。编写干净的代码也不是一件容易的事,您需要牢记许多最佳实践。以下主题突出显示了编写更好的自动化代码应获得的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上的登录功能的代码。以上内容就是本篇的全部内容以上内容希望对你有帮助,有被帮助到的朋友欢迎点赞,评论。

 如果文章对你有帮助,记得点赞,收藏,加关注。会不定期分享一些干货哦......

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

这些资料,对于想做【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!凡事要趁早,特别是技术行业,一定要提升技术功底。希望对大家有所帮助……加入我的学习交流群一起学习交流讨论把!!!!  

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

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

相关文章

2023年网络安全十大发展趋势

近日&#xff0c;中国计算机学会&#xff08;CCF&#xff09;计算机安全专委会中来自国家网络安全主管部门、高校、科研院所、大型央企、民营企业的委员投票评选出2023年网络安全十大发展趋势。 趋势一 数据安全治理成为数字经济的基石 我国《数据安全法》提出“建立健全数据…

spring的启动过程(一) :IOC容器的启动过程

一、web容器的加载 首先我们要先知道一个web项目的启动过程。 将Web项目部署到Tomcat中的方法之一&#xff0c;是部署没有封装到WAR文件中的Web项目。要使用这一方法部署未打包的webapp目录&#xff0c;只要把我们的项目&#xff08;编译好的发布项目&#xff0c;非开发项目&am…

掌握MySQL分库分表(五)SpringBoot2+MybatisPlus整合Sharding-Jdbc水平分表实现

文章目录创建Java-Maven项目创建数据库、表创建Java实体类配置启动类水平分表配置文件配置测试分库分表实现分析控制台SQL逻辑SQL真实SQL主键重复问题创建Java-Maven项目 添加依赖 <properties><java.version>11</java.version><maven.compiler.source&…

PMP考试有没有什么技巧可以介绍一下么?

一、试题形式 ——中英文对照 即每道题都是一遍英文&#xff0c;一遍翻译的中文&#xff0c;在审题的时候有一些小的技巧需要注意。首先如果你的英文水平足够好&#xff0c;建议直接阅读原文。PMP试题毕竟是美国人出的&#xff0c;语言的组织、思想的表达&#xff0c;肯定更符…

python居然能语音控制电脑壁纸切换,只需60行代码

前言 嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! 家在日常的电脑使用中&#xff0c;都会有自己喜爱类型的桌面 单纯的桌面有时候会让人觉得单调 今天&#xff0c;就由我带领大家只用60行代码打造一款语音壁纸切换器程序&#xff0c; 让大家能够通过语音的方式来控制电脑去…

c++模板的简单认识

文章目录 前言一.泛型编程 函数模板 模板参数的匹配原则 类模板总结前言 ADD函数很好写&#xff0c;但是如果我们要有int类型的&#xff0c;double类型的&#xff0c;char类型的等等各种类型&#xff0c;难道要写这么多不同的ADD函数吗&#xff0c;这么写简直太麻…

Linux:基于bufferevent epoll tcp服务器代码

基于bufferevent epoll tcp服务器代码: #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <string.h> #include <event2/event.h> #include <event2/buffer…

Excel/Word的一些快捷操作整理

Excel/Word的一些快捷操作整理 1. 给Word文件导入目录 前提&#xff1a;大致内容已经定稿&#xff0c;文章中各标题分级明确&#xff0c;最好各级标题字体大小设置不一样。 步骤&#xff1a;在头部导航栏&#xff0c;选择**“引用”–“目录”**&#xff0c;根据自己需求选择其…

KDJB1200六相继电保护测试仪

一、概述 KDJB1200继电保护测试仪是在参照电力部颁发的《微机型继电保护试验装置技术条件(讨论稿)》的基础上&#xff0c;广泛听取用户意见&#xff0c;总结目前国内同类产品优缺点&#xff0c;充分使用现代新的的微电子技术和器件实现的一种新型小型化微机继电保护测试仪。可…

DataWhale 大数据处理技术组队学习task3

四、分布式数据库HBase 1. 产生背景 1.1 Hadoop的局限性 优点&#xff1a;存储结构化、半结构甚至非结构化的数据&#xff0c;是传统数据库的补充&#xff0c;是海量数据存储的最佳方法。缺陷&#xff1a; 只能进行批处理&#xff0c;并且只能以顺序的方式访问数据。&#x…

【C++】-- 异常

目录 C语言传统的处理错误的方式 C异常概念 异常的使用 异常的抛出和捕获 自定义异常体系 异常的重新抛出 异常安全 异常规范&#xff08;C期望&#xff09; C标准库的异常体系 异常的优缺点 C异常的优点 C异常的缺点 总结 C语言传统的处理错误的方式 传统的错误…

zookeeper单机部署

一.下载zookeeper压缩包 二.上传解压安装包到/data/zookeeper目录&#xff0c;并解压 tar -zxvf apache-zookeeper-3.5.8-bin.tar.gz 三.修改配置文件 cd apache-zookeeper-3.5.10-bin/conf mv zoo_sample.cfg zoo.cfg vi zoo.cfg 修改为如下&#xff1a; dataDir/data/zooke…

【研究空间复用及函数调用问题】

本篇总结函数调用过程会存在的一些奇怪现象&#xff0c;空间复用问题&#xff0c;其实本质上涉及函数调用的底层原理&#xff0c;理解函数栈帧的创建和销毁这样的问题直接迎刃而解。1.空间复用问题案例1案例22.函数调用过程不清晰问题案例33.总结1.空间复用问题 案例1 我们先…

程职场人必备微软出品的实用小工具

系统增强工具PowerToys 下载地址&#xff1a;https://github.com/microsoft/PowerToys 什么是 Windows 系统中&#xff0c;最好的辅助工具&#xff1f; PowerToys 一定可以获得提名。PowerToys 是一款来自微软的系统增强工具&#xff0c;就像是一个神奇的系统外挂&#xff0c;…

精确控制 AI 图像生成的破冰方案,ControlNet 和 T2I-Adapter

ControlNet 和 T2I-Adapter 的突破性在哪里&#xff1f;有什么区别&#xff1f;其它为 T2I 扩散模型施加条件引导的相关研究ControlNet 和 T2I-Adapter 的实际应用效果如何&#xff1f;使用体验上&#xff0c;跟 SD原生支持的 img2img 有什么区别&#xff1f;ControlNet 在插画…

电商数据采集——2022年中国手机行业数据浅析

据国家统计局数据显示&#xff0c;2022年12月&#xff0c;国内手机产量当期值为14310.3万台&#xff0c;同比下降18.4%&#xff1b;累计值为156080万台&#xff0c;同比下降6.2%。 据中国信通院数据显示&#xff0c;2022年12月&#xff0c;国内市场手机出货量2786.0万部&#x…

F.pad() 函数

F.pad() 对tensor 进行扩充的函数。 torch.nn.functional.pad (input, pad, mode‘constant’, value0) input&#xff1a;需要扩充的 tensor&#xff0c;可以是图像数据&#xff0c;亦或是特征矩阵数据&#xff1b;pad&#xff1a;扩充维度&#xff0c;预先定义某维度上的扩充…

内存泄露定位手段(c语言hook malloc相关方式)

如何确定有内存泄露问题&#xff0c;如何定位到内存泄露位置&#xff0c;如何写一个内存泄漏检测工具&#xff1f; 1&#xff1a;概述 内存泄露本质&#xff1a;其实就是申请调用malloc/new&#xff0c;但是释放调用free/delete有遗漏&#xff0c;或者重复释放的问题。 内存…

搞懂事件——C# 的event的机制深度理解

📢欢迎点赞 :👍 收藏 ⭐留言 📝 如有错误敬请指正,赐人玫瑰,手留余香!📢本文作者:由webmote 原创📢作者格言:无尽的折腾后,终于又回到了起点,工控,我来了 !1. 前言 为什么忽然对Event感兴趣了? 因为进入Web时代以后,很少使用它了,忽然想起这个知识点,…

STM32 CAN波特率计算

STM32 CAN波特率计算简介CAN总线收发&#xff0c;中断方式接收配置代码部分reference简介 CAN通信帧共分为数据帧、远程帧、错误帧、过载帧和帧间隔&#xff0c;本文这里以数据帧为例。 显性电平对应逻辑0&#xff0c;CAN_H和CAN_L之差为2.5V左右。而隐性电平对应逻辑1&#x…