【自动化测试】【Jest-Selenium】(02)—— Jest 匹配器

时间:2022-07-26
本文章向大家介绍【自动化测试】【Jest-Selenium】(02)—— Jest 匹配器,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

1. 什么是匹配器?

使用不同匹配器可以测试输入输出的值是否符合预期。

例如:下面的 toBe、toBeGreaterThan 都是匹配器。

test('two plus two is four', () => {
  expect(2 + 2).toBe(4);
  expect(2 + 2).toBeGreaterThan(3);
});

2. 普通匹配

2.1. toBe(value)

Use .toBe to compare primitive values or to check referential identity of object instances. It calls Object.is to compare values, which is even better for testing than === strict equality operator.

注意:Don't use .toBe with floating-point numbers.

const can = {
  name: 'pamplemousse',
  ounces: 12,
};

describe('the can', () => {
  test('has 12 ounces', () => {
    expect(can.ounces).toBe(12);
  });

  test('has a sophisticated name', () => {
    expect(can.name).toBe('pamplemousse');
  });
});

2.2. toBeNull()、toBeUndefined()、toBeDefined()

.toBeNull() is the same as .toBe(null)

test('null-defined', () => {
    expect(null).toBeNull();
    expect(undefined).not.toBeNull();
    expect(undefined).toBeUndefined();
    expect(null).not.toBeUndefined();
    expect(null).toBeDefined();
});

2.3. toBeNaN()

Use .toBeNaN when checking a value is NaN.

test('passes when value is NaN', () => {
  expect(NaN).toBeNaN();
  expect(1).not.toBeNaN();
});

2.4. toBeTruthy()、toBeFalsy()

  • Use .toBeTruthy when you don't care what a value is and you want to ensure a value is true in a boolean context.
  • .Use .toBeFalsy when you don't care what a value is and you want to ensure a value is false in a boolean context.
test('toBeTruthy-toBeFalsy', () => {
    expect(1).toBeTruthy();
    expect("a").toBeTruthy();
    expect({}).toBeTruthy();
    expect([]).toBeTruthy();
    expect(true).toBeTruthy();
    expect("false").toBeTruthy();

    expect("").toBeFalsy();
    expect(0).toBeFalsy();
    expect(false).toBeFalsy();
    expect(NaN).toBeFalsy();
});

3. 字符串匹配

3.1. toMatch(regexpOrString)

Use .toMatch to check that a string matches a regular expression.

test('there is no I in team', () => {
    expect('team').not.toMatch(/in team$/);
});

test('but there is a "stop" in Christoph', () => {
    expect('Christoph').toMatch(/stop/);
});

4. 数值匹配

  • .toBeGreaterThan(number | bigint)
    • received > expected
  • .toBeGreaterThanOrEqual(number | bigint)
    • received >= expected
  • .toBeLessThan(number | bigint)
    • received < expected
  • .toBeLessThanOrEqual(number | bigint)
    • received <= expected
  • .toBeCloseTo(number, numDigits?)
    • Use toBeCloseTo to compare floating point numbers for approximate equality.
test('number', () => {
    expect(10).toBeGreaterThan(5);
    expect(10).toBeGreaterThanOrEqual(10);
    expect(10).toBeLessThan(20);
    expect(10).toBeLessThanOrEqual(10);
    expect(0.1 + 0.2).toBeCloseTo(0.3);
    expect(0.1 + 0.2).not.toBe(0.3); // 特别注意
});

5. 数组匹配

5.1. toContain(item)

Use .toContain when you want to check that an item is in an array. For testing the items in the array, this uses ===, a strict equality check. .toContain can also check whether a string is a substring of another string.

test('', () => {
    expect(["lime", "abc", "bcd"]).toContain('lime');
});

5.2. toHaveLength(number)

Use .toHaveLength to check that an object has a .length property and it is set to a certain numeric value.

test('', () => {
    expect([1, 2, 3]).toHaveLength(3);
    expect('abc').toHaveLength(3);
});

6. 对象匹配

6.1. toBeInstanceOf(Class)

Use .toBeInstanceOf(Class) to check that an object is an instance of a class.

test('', () => {
    class A {}
    expect(new A()).toBeInstanceOf(A);
    expect(() => {}).toBeInstanceOf(Function);
    expect(new A()).toBeInstanceOf(Object); // throws
});

6.2. toEqual(value)

Use .toEqual to compare recursively all properties of object instances (also known as "deep" equality). It calls Object.is to compare primitive values.

test('', () => {
    expect({
        flavor: 'grapefruit',
        ounces: 12,
    }).toEqual({
        flavor: 'grapefruit',
        ounces: 12,
    });

    expect([1, 2, 3]).not.toBe([1, 2, 3]);

    expect([1, 2, {
        flavor: 'grapefruit',
        ounces: 12,
    }]).not.toBe([1, 2, {
        flavor: 'grapefruit',
        ounces: 12,
    }]);
});

6.3. toHaveProperty(keyPath, value?)

Use .toHaveProperty to check if property at provided reference keyPath exists for an object.

  • You can provide an optional value argument to compare the received property value (recursively for all properties of object instances, also known as deep equality, like the toEqual matcher).
// Object containing house features to be tested
const houseForSale = {
    bath: true,
    bedrooms: 4,
    kitchen: {
        amenities: ['oven', 'stove', 'washer'],
        area: 20,
        wallColor: 'white',
        'nice.oven': true,
    },
    'ceiling.height': 2,
};

test('this house has my desired features', () => {
    // Example Referencing
    expect(houseForSale).toHaveProperty('bath');
    expect(houseForSale).toHaveProperty('bedrooms', 4);

    expect(houseForSale).not.toHaveProperty('pool');

    // Deep referencing using dot notation
    expect(houseForSale).toHaveProperty('kitchen.area', 20);
    expect(houseForSale).toHaveProperty('kitchen.amenities', [
        'oven',
        'stove',
        'washer',
    ]);

    expect(houseForSale).not.toHaveProperty('kitchen.open');

    // Deep referencing using an array containing the keyPath
    expect(houseForSale).toHaveProperty(['kitchen', 'area'], 20);
    expect(houseForSale).toHaveProperty(
        ['kitchen', 'amenities'],
        ['oven', 'stove', 'washer'],
    );
    expect(houseForSale).toHaveProperty(['kitchen', 'amenities', 0], 'oven');
    expect(houseForSale).toHaveProperty(['kitchen', 'nice.oven']);
    expect(houseForSale).not.toHaveProperty(['kitchen', 'open']);

    // Referencing keys with dot in the key itself
    expect(houseForSale).toHaveProperty(['ceiling.height'], 2);
});

6.4. toMatchObject(object)

Use .toMatchObject to check that a JavaScript object matches a subset of the properties of an object. It will match received objects with properties that are not in the expected object.

  • You can also pass an array of objects, in which case the method will return true only if each object in the received array matches (in the toMatchObject sense described above) the corresponding object in the expected array.
const houseForSale = {
    bath: true,
    bedrooms: 4,
    kitchen: {
        amenities: ['oven', 'stove', 'washer'],
        area: 20,
        wallColor: 'white',
    },
};
const desiredHouse = {
    bath: true,
    kitchen: {
        amenities: ['oven', 'stove', 'washer'],
        wallColor: expect.stringMatching(/white|yellow/),
    },
};

test('the house has my desired features', () => {
    expect(houseForSale).toMatchObject(desiredHouse);
});

test('the number of elements must match exactly', () => {
    expect([{foo: 'bar'}, {baz: 1}]).toMatchObject([{foo: 'bar'}, {baz: 1}]);
});

test('.toMatchObject is called for each elements, so extra object properties are okay', () => {
    expect([{foo: 'bar'}, {baz: 1, extra: 'quux'}]).toMatchObject([
        {foo: 'bar'},
        {baz: 1},
    ]);
});

6.5. toStrictEqual(value)

Use .toStrictEqual to test that objects have the same types as well as structure.

  • Keys with undefined properties are checked. e.g. {a: undefined, b: 2} does not match {b: 2} when using .toStrictEqual.
  • Array sparseness is checked. e.g. [, 1] does not match [undefined, 1] when using .toStrictEqual.
  • Object types are checked to be equal. e.g. A class instance with fields a and b will not equal a literal object with fields a and b.
class LaCroix {
    constructor(flavor) {
        this.flavor = flavor;
    }
}

test('are not semantically the same', () => {
    expect(new LaCroix('lemon')).toEqual({flavor: 'lemon'});
    expect(new LaCroix('lemon')).not.toStrictEqual({flavor: 'lemon'});
});

7. 异常匹配

7.1. toThrow(error?)

Use .toThrow to test that a function throws when it is called.

function myfn(){
    console.log(X);
}

test('throws on octopus', () => {
    expect(() => {
        myfn();
    }).toThrow();
});