WEB自动化-04-Cypress 测试用例编写和组织

4 测试用例编写和组织

4.1 用例结构

Cypress是建立在 MochaChai之上,因此同时支持Chai的 BDDTDD两种风格。如果你熟悉JavaScript风格的代码,那么在Cypress中写测试用例是很容易上手的。

Mocha是一款适用于Node.js和浏览器的测试框架,可使用异步测试变得简单灵活。

Cypress的测试风格继承于Mocha,提供了 describe()context()it()specify()四个关键字,对于一条可执行的测试而言,必须包含以下两个组成部分:

  • describe()context()等效,均表示一个测试套件或测试集
  • it()specify()等效,均表示一个测试用例

示例如下所示:

describe('我是一个测试集', () => {
    it('测试用例-1', () => {
        expect(1+2).to.eq(3)
    });
    it('测试用例-2', () => {
        expect(3-2).to.eq(1)
    });
    it('测试用例-3', () => {
        expect(3*2).to.eq(5)
    });
});

最终的运行结果如下所示:

WEB自动化-04-Cypress 测试用例编写和组织

4.2 Hook

Hook中文常翻译为 钩子函数,Cypress也提供了Hook(从Mocha继承而来)。这些Hook函数能够在运行每个测试用例或测试集之前,做一些准备操作,也可以每个测试用例或测试集运行完成之后执行一些操作。示例如下所示:

///

before(()=>{
    // 全局Hook
    // 所有用例运行行前执行,但仅执行一次
    cy.log("我是全局before Hook,所有测试用例运行前执行我,但仅执行一次")
});

beforeEach(()=>{
    // 全局Hook
    // 每个测试用例运行前执行
    cy.log("我是全局beforeEach Hook,每个测试用例运行前执行我")
});

afterEach(()=>{
    // 全局Hook
    // 每个测试用例运行完成后执行
    cy.log("我是全局afterEach Hook,每个测试用例运行完成后执行我")
});

after(()=>{
    // 全局Hook
    // 所有测试用例运行完成后执行,但仅执行一次
    cy.log("我是全局after Hook,所有测试用例运行完成后执行,但仅执行一次")
});

describe('Test Hooks in TestSuite', () => {
    before(()=>{
        // 当前测试集Hook
        // 当前测试集中,所有测试用例运行前执行,但仅执行一次
        cy.log("我是当前测试集before Hook,所有测试用例运行前执行我,但仅执行一次")
    });

    beforeEach(()=>{
        // 当前测试集Hook
        // 当前测试集中,每个测试用例运行前执行
        cy.log("我是当前测试集beforeEach Hook,每个测试用例运行前执行我")
    });

    afterEach(()=>{
        // 当前测试集Hook
        // 当前测试集中,每个测试用例运行完成后执行
        cy.log("我是当前测试集afterEach Hook,每个测试用例运行完成后执行我")
    });

    after(()=>{
        // 当前测试集Hook
        // 当前测试集中,所有测试用例运行完成后执行,但仅执行一次
        cy.log("我是当前测试集after Hook,所有测试用例运行完成后执行,但仅执行一次")
    });

    it('Test Hook in case-1', () => {
        cy.log("我是测试用例-1");
        cy.visit("https://www.baidu.com/",{timeout:10000});
    });
    it('Test Hook in case-2', () => {
        cy.log("我是测试用例-2");
        cy.visit("https://www.baidu.com/",{timeout:10000});
    });
});

最终的运行结果如下所示:

WEB自动化-04-Cypress 测试用例编写和组织

从以上示例代码可以总结出来运行顺序如下所示:

  • 仅在测试开始时运行 before且仅运行一次
  • 任何一个用例运行前都要运行 beforeEach
  • 运行测试用例
  • 任何一个用例结束时都要运行 afterEach
  • 仅在测试结束时运行 after且仅运行一次

4.2.1 before()/after()

before()是所有测试用例的 统一前置动作,而before()在一个describe()内只会执行一次,其执行顺序在所有测试用例it()之前。after()是所有测试用例的 统一后置动作,而after()在一个describe()内只会执行一次,其执行顺序在所有测试用例it()之后。示例代码如下所示:

///

describe('', () => {
    let baseUrl="https://example.cypress.io/todo";
    before(()=>{
      cy.log("所有用例运行前执行before,仅执行一次");
    });

    it('测试用例-1', () => {
       cy.visit(baseUrl,{timeout:10000});
       cy.get(".header input").should("have.class","new-todo");
    });

    it('测试用例-2', () => {
       cy.visit(baseUrl,{timeout:10000});
       cy.get('.new-todo').type('todo A{enter}').type('todo B{enter}');
       cy.get('.todo-list li').should('have.length', 4);
    });

    after(()=>{
        cy.log("所有用例运行完成后执行after,仅执行一次");
    });
});

最终的运行结果如下所示:

WEB自动化-04-Cypress 测试用例编写和组织

4.2.2 beforeEach()/afterEach()

beforeEach()是每个测试用例执行前的 前置操作,即每个用例执行前都会执行一次。一个describe()有几个用例it()就会执行几次。afterEach()是每个测试用例执行后的 后置操作,即每个用例执行完成后都会执行一次。一个describe()有几个用例it()就会执行几次。示例代码如下所示:

///

describe('', () => {
    let baseUrl="https://example.cypress.io/todo";
    before(()=>{
      cy.log("所有用例运行前执行before,仅执行一次");
    });

    beforeEach(()=>{
      cy.log("每个用例执行前,均会执行一次beforeEach");
      cy.visit(baseUrl,{timeout:10000});
    });

    it('测试用例-1', () => {
       cy.get(".header input").should("have.class","new-todo");
    });

    it('测试用例-2', () => {
       cy.get('.new-todo').type('todo A{enter}').type('todo B{enter}');
       cy.get('.todo-list li').should('have.length', 4);
    });

    afterEach(()=>{
      cy.log("每个用例执行完成后,均会执行afterEach");
    });

    after(()=>{
        cy.log("所有用例运行完成后执行after,仅执行一次");
    });
});

最终的运行结果如下所示:

WEB自动化-04-Cypress 测试用例编写和组织

4.3 包含/排队用例

通过学习Hook,我们可以把测试的前置和后置条件进行剥离,更好的编写和组织测试用例。在实际项目中,我们也需要仅运行指定的测试用例或跳过某些用例等。Cypress也提供相应的功能,一起来看看吧。

4.3.1 包含测试集/测试用例

在Cypress提供该功能的是 .only()当使用.only()指定某个测试集/测试用例后,仅当指定了的测试集/测试用例才会运行,其他未指定的测试集/测试用例则不会运行。示例如下所示:

  • *1.仅运行指定测试集
///

describe.only('包含only', () => {
    let baseUrl="https://example.cypress.io/todo";
    before(()=>{
      cy.log("所有用例运行前执行before,仅执行一次");
    });

    beforeEach(()=>{
      cy.log("每个用例执行前,均会执行一次beforeEach");
      cy.visit(baseUrl,{timeout:20000});
    });

    it('测试用例-1', () => {
       cy.get(".header input").should("have.class","new-todo");
    });

    it('测试用例-2', () => {
       cy.get('.new-todo').type('todo A{enter}').type('todo B{enter}');
       cy.get('.todo-list li').should('have.length', 4);
    });

    afterEach(()=>{
      cy.log("每个用例执行完成后,均会执行afterEach");
    });

    after(()=>{
        cy.log("所有用例运行完成后执行after,仅执行一次");
    });
});

describe('不包含only', () => {
  let tempUrl="https://www.baidu.com";
  beforeEach(()=>{
     cy.visit(tempUrl);
  });

  it('不包含only测试用例-1', () => {
      cy.get("#kw").type("Surpass{Enter}");
      // cy.get("#kw").type("Surpass");
      // cy.get("#su").click();
  });

  afterEach(()=>{
    cy.log("每个用例执行完成后,均会执行afterEach");
  });
});

最终的运行结果如下所示:

WEB自动化-04-Cypress 测试用例编写和组织
  • *2.仅运行指定测试用例
describe.only('包含only', () => {
    let baseUrl="https://example.cypress.io/todo";
    before(()=>{
      cy.log("所有用例运行前执行before,仅执行一次");
    });

    beforeEach(()=>{
      cy.log("每个用例执行前,均会执行一次beforeEach");
      cy.visit(baseUrl,{timeout:20000});
    });

    it('测试用例-1', () => {
       cy.get(".header input").should("have.class","new-todo");
    });

    it.only('测试用例-2', () => {
       cy.get('.new-todo').type('todo A{enter}').type('todo B{enter}');
       cy.get('.todo-list li').should('have.length', 4);
    });

    afterEach(()=>{
      cy.log("每个用例执行完成后,均会执行afterEach");
    });

    after(()=>{
        cy.log("所有用例运行完成后执行after,仅执行一次");
    });
});

最终的运行结果如下所示:

WEB自动化-04-Cypress 测试用例编写和组织

4.3.2 排除测试集/测试用例

在Cypress提供该功能的是 .skip()当使用.skip()指定某个测试集/测试用例后,则不会运行该测试集/测试用例,其他未指定的测试集/测试用例则会运行。示例如下所示:

  • *1.排除指定测试集
///

describe('包含only', () => {
    let baseUrl="https://example.cypress.io/todo";
    before(()=>{
      cy.log("所有用例运行前执行before,仅执行一次");
    });

    beforeEach(()=>{
      cy.log("每个用例执行前,均会执行一次beforeEach");
      cy.visit(baseUrl,{timeout:20000});
    });

    it('测试用例-1', () => {
       cy.get(".header input").should("have.class","new-todo");
    });

    it.only('测试用例-2', () => {
       cy.get('.new-todo').type('todo A{enter}').type('todo B{enter}');
       cy.get('.todo-list li').should('have.length', 4);
    });

    afterEach(()=>{
      cy.log("每个用例执行完成后,均会执行afterEach");
    });

    after(()=>{
        cy.log("所有用例运行完成后执行after,仅执行一次");
    });
});

describe.skip('不包含only', () => {
  let tempUrl="https://www.baidu.com";
  beforeEach(()=>{
     cy.visit(tempUrl);
  });

  it('不包含only测试用例-1', () => {
      cy.get("#kw").type("Surpass{Enter}");
      // cy.get("#kw").type("Surpass");
      // cy.get("#su").click();
  });

  afterEach(()=>{
    cy.log("每个用例执行完成后,均会执行afterEach");
  });
});

最终的运行结果如下所示:

WEB自动化-04-Cypress 测试用例编写和组织
  • *2.排除指定测试用例
describe('顶层测试集', () => {
    let baseUrl="https://example.cypress.io/todo";
    before(()=>{
      cy.log("所有用例运行前执行before,仅执行一次");
    });

    beforeEach(()=>{
      cy.log("每个用例执行前,均会执行一次beforeEach");
      cy.visit(baseUrl,{timeout:20000});
    });

    it('测试用例-1', () => {
       cy.get(".header input").should("have.class","new-todo");
    });

    it.skip('测试用例-2', () => {
       cy.get('.new-todo').type('todo A{enter}').type('todo B{enter}');
       cy.get('.todo-list li').should('have.length', 4);
    });

    describe.skip('嵌套测试集', () => {
      it('嵌套测试集用例-1', () => {
          cy.log("测试嵌套用例集");
      });
    });

    afterEach(()=>{
      cy.log("每个用例执行完成后,均会执行afterEach");
    });

    after(()=>{
        cy.log("所有用例运行完成后执行after,仅执行一次");
    });
});

最终的运行结果如下所示:

WEB自动化-04-Cypress 测试用例编写和组织

从上面示例中可以看出,标记为被排除的测试集后,则该测试集所有测试用例均不被执行

在实际项目中,only()和skip()通常是结合着使用,这时我们要先看标记describe的是skip()还是only(),其规则如下所示:

  • 如果先标记describe的是skip(),则整个测试用例集都将被排除,不执行
  • 如果先标记describe的是only(),若该用例集下,没有任何标记skip的用例,则所有用例都将运行
  • 如果先标记describe的是only(),若该用例集下,如果有标记only的用例,则将仅运行标记了only的用例
  • 如果describe和it均没有skip/only,则默认运行所有测试集或用例

4.4 动态执行测试用例

前面学习如何排除和执行指定测试集/测试用例,但在一些实际项目中,在执行用例的时候,会根据某一个条件来动态执行测试用例。为了解决这个问题,Cyrpess也提供相应的功能,通过更改相应的测试配置来支持。其语法格式如下所示:

describe(name, config, fn)
context(name, config, fn)
it(name, config, fn)
specify(name, config, fn)

部分配置参数为只读,不支持修改,可参考官网:https://docs.cypress.io/guides/references/configuration##Test-Configuration

    1. *测试用例集配置

示例代码如下所示:

///

describe('When not in Chrome',{browser:"!chrome"}, () => {
    let baseUrl="https://example.cypress.io/todo";

    it.only('Show warnings', () => {
       cy.visit(baseUrl,{timeout:20000});
       cy.get(".header input").should("have.class","new-todo");
    });

    it.only('测试用例-2', () => {
    cy.visit(baseUrl,{timeout:20000});
       cy.get('.new-todo').type('todo A{enter}').type('todo B{enter}');
       cy.get('.todo-list li').should('have.length', 4);
    });

});

在Chrome中运行时其结果如下所示:

WEB自动化-04-Cypress 测试用例编写和组织

下面的示例,将仅运行在指定的浏览器中,且指定的分辨率和环境变量将覆盖默认的值,如下所示:

///

describe('When in Chrome',
   {
       browser:"chrome",
       viewportWidth: 800,
       viewportHeight: 600,
       env: {
         flag: true,
         url: "https://www.surpassme.com",
       },

   },
   () => {
    let baseUrl="https://example.cypress.io/todo";

    it.only('Show warnings', () => {
       cy.visit(baseUrl,{timeout:20000});
       cy.get(".header input").should("have.class","new-todo");
    });

    it.only('测试用例-2', () => {
    cy.visit(baseUrl,{timeout:20000});
       cy.get('.new-todo').type('todo A{enter}').type('todo B{enter}');
       cy.get('.todo-list li').should('have.length', 4);
    });

});

运行时其结果如下所示:

WEB自动化-04-Cypress 测试用例编写和组织
    1. *单个测试用例配置

示例代码如下所示:

///

describe('When in Chrome', () => {
    let baseUrl="https://example.cypress.io/todo";

    it.only('Show warnings',
        {
            retries: {
                runMode: 3,
                openMode: 2
            }
        },
        () => {
        cy.visit(baseUrl,{timeout:20000});
        cy.get(".header input").should("have.class","new-todo");
        });

    it.only('测试用例-2', () => {
        cy.visit(baseUrl,{timeout:20000});
       cy.get('.new-todo').type('todo A{enter}').type('todo B{enter}');
       cy.get('.todo-list li').should('have.length', 4);
    });

});

4.5 动态生成测试用例

在实际项目中,会遇到一种情况,就是多个用例的操作步骤、断言均一样,仅是输入和输出不一样。如果我还是一条数据写一个用例,则效率会非常低。此时,我们可以利用Cypress动态生成测试用例来高效完成。我们以登录为例,如下所示:

  • 1.创建一个postdata.json格式的数据文件
[
    {
        "title": "测试数据-1",
        "customerName": "Surpass",
        "telephone": "18812345678",
        "email":"ceo@surpass.com"
    },
    {
        "title": "测试数据-2",
        "customerName": "kevin",
        "telephone": "17808231169",
        "email":"hr@surpass.com"
    }
]
  • 2.创建测试用例
///

import data from "./postdata.json"

describe("测试发送数据", () => {
    let baseUrl="http://httpbin.org/forms/post";
    beforeEach(()=>{
        cy.visit(baseUrl)
    });
    data.forEach( item => {
        it(item.title, () => {
            cy.log(item.title,item.customerName,item.telephone)
            cy.get(":nth-child(1) > label > input").type(item.customerName).should("contain.value",item.customerName);
            cy.get("form > :nth-child(2) > label > input").type(item.telephone).should("contain.value",item.telephone);
            cy.get("form > :nth-child(3) > label > input").type(item.email).should("contain.value",item.email);
        });
    })
})

运行时其结果如下所示:

WEB自动化-04-Cypress 测试用例编写和组织

如果大家对数据驱动比较了解的话,从上面的示例可以看到,是不是非常像?其最大价值为测试数据更改时,不影响测试代码。

4.6 断言风格

Cypress支持两种风格的断言 BDD (expect/should) 和 TDD (assert),以下列举常见的断言:

  • 1、针对长度(Length)的断言
cy.get('.todo-list li').should('have.length', 4);
  • 2、针对类(Class)的断言
cy.get("form").find("input").should("not.have.class","surpass");
  • 3、针对值(Value)的断言
 cy.get("form > :nth-child(3) > label > input").should("contain.value","Surpass");
  • 4、针对文本内容(Text)的断言
cy.get("button").should("contain.text","Submit order");
// 或
cy.get("button").should("not.contain","Surpass");
  • 5、针对元素是否可见(Visible)的断言
cy.get("button").should("be.visible");
  • 6、判断元素是否存在的断言
cy.get("button").should("not.exist");
  • 7、判断元素状态(State)的断言
cy.get(":nth-child(4) > :nth-child(2) > label > input").click().should("be.checked");
  • 8、针对CSS的断言
cy.get(".surpass").should("have.css","line-surpass");

4.7 运行测试用例

4.7.1 运行单个用例

运行单个测试用例,可以获得到更好的性能。在Test Runner界面, 点击单个JS文件即可,其操作方法如下所示:

WEB自动化-04-Cypress 测试用例编写和组织

4.7.2 运行所有用例

运行所有测试用例,可以在Test Runner中单击运行 Run x integration specs

WEB自动化-04-Cypress 测试用例编写和组织

4.7.3 运行部分用例

可以通过 筛选从而仅运行符合筛选条件的用例。

WEB自动化-04-Cypress 测试用例编写和组织

筛选条件中忽略大小写

4.8 测试运行状态

在Cypress中,测试用例的运行状态可以分为4种状态: 通过(Passed)失败(Failed)等待(Pending)跳过(Skipped)

4.8.1 Passed

Passed表示测试用例的运行状态为通过,没有出现断言失败的情况。如下所示:

WEB自动化-04-Cypress 测试用例编写和组织

4.8.2 Failed

Failed表示测试用例的运行状态为失败,有出现断言失败的情况。如下所示:

WEB自动化-04-Cypress 测试用例编写和组织

4.8.3 Pending

当一个测试用例没有想好怎么写时,我们可以写一些占位性质的用例,虽然Cypress不会运行,但却会让后续的用例状态处于Pending状态,如下所示:

///

describe('测试Pending场景', () => {
    it('未完成的测试用例')

    it.skip('已经完成的用例', () => {
        let url="http://httpbin.org/forms/post";
        let customerName="Surpass",telephone="18812345678",email="ceo@surpass.com",textMsg="I Love Surpass",buttonText="Submit order";
        cy.visit(url,{timeout:10000});
        cy.get(":nth-child(1) > label > input").type(customerName).should("contain.value",customerName);
        cy.get("form > :nth-child(2) > label > input").type(telephone).should("contain.value",telephone);
        cy.get("form > :nth-child(3) > label > input").type(email).should("contain.value",email);
        cy.get("textarea").type(textMsg).should("contain.value",textMsg);
        cy.get("button").should("contain.text",buttonText)
    });

    xit("另一种测试用例",()=>{
        expect(false).to.true;
    });
});

运行时其结果如下所示:

WEB自动化-04-Cypress 测试用例编写和组织

以上三种情况的用例均会标识为Pending状态

如果用例编写人员故意使用以上三种方式中的其中一种方式来跳过执行用例,则Cypress将视为Pending Test

4.8.4 Skipped

当一个测试用例本来要执行,但却因为某些原因而未能运行,则Cypress会将该用例的运行状态视为Skipped。我们在一个测试集里面添加beforeEach(),示例代码如下所示:

///

describe('测试用例状态为Skipped场景', () => {
    let baseUrl="https://example.cypress.io/todo";
    beforeEach(()=>{
        cy.visit(baseUrl);
    });

    it('hides footer initially', () => {
        cy.get('.filters').should('be.exist');
    });

    it('adds 2 todos', () => {
        cy.get('.new-todo').type('learn testing{enter}').type('be cool{enter}');
        cy.get('.todo-list li').should('have.length', 4);
      })
});

以上这种情况,所有测试用例能顺利执行并通过,如下所示:

WEB自动化-04-Cypress 测试用例编写和组织

我们修改以上代码,让beforeEach()访问的地址不存在,再来看看,如下所示:

///

describe('测试用例状态为Skipped场景', () => {
    let baseUrl="https://example.cypress.io/todo";
    beforeEach(()=>{
        cy.visit(baseUrl+"/does-not-exist");
    });
    it('hides footer initially', () => {
        cy.get('.filters').should('be.exist');
    });

    it('adds 2 todos', () => {
        cy.get('.new-todo').type('learn testing{enter}').type('be cool{enter}');
        cy.get('.todo-list li').should('have.length', 4);
      })
});

运行结果如下所示:

WEB自动化-04-Cypress 测试用例编写和组织

在上述示例代码中,用例adds 2 todos本来想运行,但却因为beforeEach出现问题,而未能运行,最终被标识为Skipped。

4.9 Test Runner简介

我们先来看看Test Runner的截图如下所示:

WEB自动化-04-Cypress 测试用例编写和组织

Cypress自带的Test Runner功能非常强大,允许在测试运行期间查看测试命令的执行情况,并监控在命令执行时,被测试程序所处的状态。其组成部分如下所示:

  • *1.测试状态目录

在上图 标识为1的区域,用于展示测试用例运行成功、失败的数量、运行时间、禁用自动滚动和重新运行按钮等

  • *2.运行命令日志

在上图 标识为2的区域,用于记录每个执行的命令。鼠标单击,可以在应用程序预览(标识为5的区域)中查看其对应的元素及其执行详细信息。

  • *3.元素定位辅助器

在上图 标识为3的区域,通过该功能可以快速定位元素。如下所示:

WEB自动化-04-Cypress 测试用例编写和组织
  • *4.URL预览栏

在上图 标识为4的区域,通过URL预览栏,可以查看被测试程序运行进所对应的URL地址。

  • *5.应用程序预览

在上图 标识为5的区域,通过应用程序预览窗口,可以展示应用程序在测试运行中的实时状态

  • *6.视窗大小窗口

在上图 标识为6的区域,通过视窗大小可以了解当前应用程序运行时的视窗大小。如下所示:

WEB自动化-04-Cypress 测试用例编写和组织

原文地址:https://www.jianshu.com/p/203049b059f4

本文同步在微信订阅号上发布,如各位小伙伴们喜欢我的文章,也可以关注我的微信订阅号:woaitest,或扫描下面的二维码添加关注:

WEB自动化-04-Cypress 测试用例编写和组织

Original: https://www.cnblogs.com/surpassme/p/16671287.html
Author: Surpassme
Title: WEB自动化-04-Cypress 测试用例编写和组织

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/581633/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • rocksdb列族笔记

    1、简介 列族(Column Families)是rocksdb3.0提出的一个机制,用于对同一个数据库的记录(键值对)进行逻辑划分。默认情况下所有的记录都会存储在一个默认列族里(…

    Linux 2023年6月7日
    0100
  • 在公司当上PD的心路历程

    前不久因为接了个新项目,我被选中当上PD也就是专门负责给客户演示,推进项目、录视频、写文档、做测试,因为我本来就需要测这些东西,熟悉算法、应用、固件,所以大部分人就觉得非我不可。 …

    Linux 2023年6月8日
    095
  • Java动态脚本Groovy获取Bean(奇淫技巧操作)

    前言:请各大网友尊重本人原创知识分享,谨记本人博客: 南国以南i 背景: 在Java代码中当我们需要一个Bean对象,通常会使用spring中@Autowired注解,用来自动装配…

    Linux 2023年6月14日
    095
  • 小记:音频格式转化ByPython(下)

    上文中我们已经大致明白了pydub库的使用方法,今天的目标是写个爬虫爬取歌曲信息。 关于网络爬虫,Python的标准库里是有相应的包的,可以直接打开:https://docs.py…

    Linux 2023年6月8日
    099
  • [ Skill ] 如何获取库中的 top cell

    https://www.cnblogs.com/yeungchie/ top cell 的一个特点就是没有被其他的单元所调用,下面举例获取某个库中的 top cell。 1. 获取…

    Linux 2023年6月7日
    086
  • 安装一些服务:termux奇门遁甲

    接下来就是开始服务了 作为最基础的ssh,连接肯定是用ssh了,不然总用use线去连接手机吧 首先要给手机一个ip地址,连接wifi的时候,可以的话就固定mac,静态ip地址 方法…

    Linux 2023年6月8日
    0122
  • [20210930]bbed读取数据块7 fffext.sh.txt

    [20210930]bbed读取数据块7 fffext.sh.txt –//一般bash shell脚本很少考虑执行效率,仅仅考虑利用它快速解决工作中遇到的问题. &#…

    Linux 2023年6月13日
    083
  • 自己写的文件夹图标修改脚本

    自己写了一个文件图标修改的Python脚本,只要把文件夹拖动到这个脚本上,就可以用文件夹中的图片和视频作为文件夹的封面。把图片或视频拖到脚本上,就可以把这个图片或视频用作其所在文件…

    Linux 2023年6月6日
    0151
  • Python schedule 库定时任务

    Python schedule 库定时任务 schedule的使用 用于scrapy定时任务设置 import schedule import time def job(): pr…

    Linux 2023年6月13日
    092
  • vi和vim文本编辑器

    vi和vim文本编辑器 vi和vim模式的相互切换 快捷键使用案例 拷贝当前行yy; 拷贝当前行向下的5行 5yy; 并粘贴(p) 删除当前行dd; 删除当前行向下的5行 5dd …

    Linux 2023年6月11日
    092
  • 事务与事务隔离级别详解

    事务基本概念 一组要么同时执行成功,要么同时执行失败的SQL 语句。是数据库操作的一个执行单元。 事务开始于: 连接到数据库上,并执行一条DML 语句in sert 、update…

    Linux 2023年6月14日
    095
  • 如何利用XShell隧道通过跳板机连接内网机器

    在服务器众多的企业里,通常运维会把某台机器开放外网访问权限,其他服务器通过该机器进行访问,该机器通常称之为跳板机。开发人员可以通过SSH工具访问服务器,进行日志查看、问题排查等等。…

    Linux 2023年5月28日
    0105
  • Linux(RedHat、Ubuntu)安装docker

    Linux(RedHat、Ubuntu)安装docker 前言 docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的…

    Linux 2023年6月6日
    090
  • shell脚本执行错误:#!/bin/bash: No such file or directory

    1、问题描述: 执行.sh脚本时控制台报错 : #!/bin/bash: No such file or directory 2、解决办法: cat -A 文件路径 会发现第一行有…

    Linux 2023年5月28日
    0244
  • algorithm 头文件参考

    定义执行算法的 C++ 标准库容器模板函数。 该 <algorithm></algorithm> 库还使用该 #include <initialize…

    Linux 2023年6月7日
    0102
  • PHP array_values()

    array_values array_values() 函数返回一个包含给定数组中所有键值的数组,但不保留键名。 示例: function arrayValues() { $dat…

    Linux 2023年6月7日
    093
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球