首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Assertj+如何为可迭代对象创建自定义断言

Assertj是一个流行的Java断言库,它提供了丰富的断言方法,可以帮助开发人员编写更加清晰和可读性强的测试代码。在Assertj中,可以使用自定义断言来扩展其功能,以便更好地满足特定的测试需求。

对于可迭代对象,可以通过实现org.assertj.core.api.iterable.ThrowingExtractor接口来创建自定义断言。该接口定义了一个extractThrows方法,用于从可迭代对象中提取需要断言的值。下面是一个示例:

代码语言:txt
复制
import org.assertj.core.api.AbstractIterableAssert;
import org.assertj.core.api.Assertions;
import org.assertj.core.api.ThrowableAssert;

import java.util.function.Consumer;

public class CustomIterableAssert<T> extends AbstractIterableAssert<CustomIterableAssert<T>, Iterable<? extends T>, T> {

    protected CustomIterableAssert(Iterable<? extends T> actual) {
        super(actual, CustomIterableAssert.class);
    }

    public static <T> CustomIterableAssert<T> assertThat(Iterable<? extends T> actual) {
        return new CustomIterableAssert<>(actual);
    }

    public CustomIterableAssert<T> containsCustom(T expected) {
        isNotNull();

        for (T element : actual) {
            if (element.equals(expected)) {
                return myself;
            }
        }

        throwAssertionError("Expecting <%s> to contain <%s>", actual, expected);
        return myself;
    }

    public CustomIterableAssert<T> containsCustom(T... expected) {
        isNotNull();

        for (T element : expected) {
            containsCustom(element);
        }

        return myself;
    }

    public CustomIterableAssert<T> containsCustomExactly(T... expected) {
        isNotNull();

        hasSameSizeAs(expected);
        containsCustom(expected);

        return myself;
    }

    public CustomIterableAssert<T> containsCustomExactlyInAnyOrder(T... expected) {
        isNotNull();

        hasSameSizeAs(expected);
        containsCustomInAnyOrder(expected);

        return myself;
    }

    public CustomIterableAssert<T> containsCustomInAnyOrder(T... expected) {
        isNotNull();

        for (T element : expected) {
            containsCustom(element);
        }

        return myself;
    }

    public CustomIterableAssert<T> containsCustomOnly(T... expected) {
        isNotNull();

        containsCustomExactly(expected);

        return myself;
    }

    public CustomIterableAssert<T> containsCustomOnlyOnce(T expected) {
        isNotNull();

        containsCustom(expected);
        containsCustomExactly(expected);

        return myself;
    }

    public CustomIterableAssert<T> doesNotContainCustom(T unexpected) {
        isNotNull();

        for (T element : actual) {
            if (element.equals(unexpected)) {
                throwAssertionError("Expecting <%s> not to contain <%s>", actual, unexpected);
            }
        }

        return myself;
    }

    public CustomIterableAssert<T> doesNotContainCustom(T... unexpected) {
        isNotNull();

        for (T element : unexpected) {
            doesNotContainCustom(element);
        }

        return myself;
    }

    public CustomIterableAssert<T> doesNotContainNull() {
        isNotNull();

        for (T element : actual) {
            if (element == null) {
                throwAssertionError("Expecting <%s> not to contain null elements", actual);
            }
        }

        return myself;
    }

    public CustomIterableAssert<T> doesNotHaveDuplicates() {
        isNotNull();

        for (T element : actual) {
            int count = 0;

            for (T other : actual) {
                if (element.equals(other)) {
                    count++;
                }
            }

            if (count > 1) {
                throwAssertionError("Expecting <%s> not to have duplicates", actual);
            }
        }

        return myself;
    }

    public CustomIterableAssert<T> hasSize(int expectedSize) {
        isNotNull();

        int actualSize = 0;

        for (T element : actual) {
            actualSize++;
        }

        if (actualSize != expectedSize) {
            throwAssertionError("Expecting size of <%s> to be <%s> but was <%s>", actual, expectedSize, actualSize);
        }

        return myself;
    }

    public CustomIterableAssert<T> hasSizeGreaterThan(int expectedSize) {
        isNotNull();

        int actualSize = 0;

        for (T element : actual) {
            actualSize++;
        }

        if (actualSize <= expectedSize) {
            throwAssertionError("Expecting size of <%s> to be greater than <%s> but was <%s>", actual, expectedSize, actualSize);
        }

        return myself;
    }

    public CustomIterableAssert<T> hasSizeLessThan(int expectedSize) {
        isNotNull();

        int actualSize = 0;

        for (T element : actual) {
            actualSize++;
        }

        if (actualSize >= expectedSize) {
            throwAssertionError("Expecting size of <%s> to be less than <%s> but was <%s>", actual, expectedSize, actualSize);
        }

        return myself;
    }

    public CustomIterableAssert<T> hasSizeBetween(int lowerBound, int upperBound) {
        isNotNull();

        int actualSize = 0;

        for (T element : actual) {
            actualSize++;
        }

        if (actualSize < lowerBound || actualSize > upperBound) {
            throwAssertionError("Expecting size of <%s> to be between <%s> and <%s> but was <%s>", actual, lowerBound, upperBound, actualSize);
        }

        return myself;
    }

    public CustomIterableAssert<T> hasSameSizeAs(Iterable<?> other) {
        isNotNull();

        int actualSize = 0;
        int otherSize = 0;

        for (T element : actual) {
            actualSize++;
        }

        for (Object element : other) {
            otherSize++;
        }

        if (actualSize != otherSize) {
            throwAssertionError("Expecting size of <%s> to be <%s> but was <%s>", actual, otherSize, actualSize);
        }

        return myself;
    }

    public CustomIterableAssert<T> hasSameSizeAs(Object[] other) {
        isNotNull();

        int actualSize = 0;
        int otherSize = other.length;

        for (T element : actual) {
            actualSize++;
        }

        if (actualSize != otherSize) {
            throwAssertionError("Expecting size of <%s> to be <%s> but was <%s>", actual, otherSize, actualSize);
        }

        return myself;
    }

    public CustomIterableAssert<T> hasSameSizeAs(int[] other) {
        isNotNull();

        int actualSize = 0;
        int otherSize = other.length;

        for (T element : actual) {
            actualSize++;
        }

        if (actualSize != otherSize) {
            throwAssertionError("Expecting size of <%s> to be <%s> but was <%s>", actual, otherSize, actualSize);
        }

        return myself;
    }

    public CustomIterableAssert<T> hasSameSizeAs(long[] other) {
        isNotNull();

        int actualSize = 0;
        int otherSize = other.length;

        for (T element : actual) {
            actualSize++;
        }

        if (actualSize != otherSize) {
            throwAssertionError("Expecting size of <%s> to be <%s> but was <%s>", actual, otherSize, actualSize);
        }

        return myself;
    }

    public CustomIterableAssert<T> hasSameSizeAs(float[] other) {
        isNotNull();

        int actualSize = 0;
        int otherSize = other.length;

        for (T element : actual) {
            actualSize++;
        }

        if (actualSize != otherSize) {
            throwAssertionError("Expecting size of <%s> to be <%s> but was <%s>", actual, otherSize, actualSize);
        }

        return myself;
    }

    public CustomIterableAssert<T> hasSameSizeAs(double[] other) {
        isNotNull();

        int actualSize = 0;
        int otherSize = other.length;

        for (T element : actual) {
            actualSize++;
        }

        if (actualSize != otherSize) {
            throwAssertionError("Expecting size of <%s> to be <%s> but was <%s>", actual, otherSize, actualSize);
        }

        return myself;
    }

    public CustomIterableAssert<T> hasSameSizeAs(short[] other) {
        isNotNull();

        int actualSize = 0;
        int otherSize = other.length;

        for (T element : actual) {
            actualSize++;
        }

        if (actualSize != otherSize) {
            throwAssertionError("Expecting size of <%s> to be <%s> but was <%s>", actual, otherSize, actualSize);
        }

        return myself;
    }

    public CustomIterableAssert<T> hasSameSizeAs(byte[] other) {
        isNotNull();

        int actualSize = 0;
        int otherSize = other.length;

        for (T element : actual) {
            actualSize++;
        }

        if (actualSize != otherSize) {
            throwAssertionError("Expecting size of <%s> to be <%s> but was <%s>", actual, otherSize, actualSize);
        }

        return myself;
    }

    public CustomIterableAssert<T> hasSameSizeAs(char[] other) {
        isNotNull();

        int actualSize = 0;
        int otherSize = other.length;

        for (T element : actual) {
            actualSize++;
        }

        if (actualSize != otherSize) {
            throwAssertionError("Expecting size of <%s> to be <%s> but was <%s>", actual, otherSize, actualSize);
        }

        return myself;
    }

    public CustomIterableAssert<T> hasSameSizeAs(String other) {
        isNotNull();

        int actualSize = 0;
        int otherSize = other.length();

        for (T element : actual) {
            actualSize++;
        }

        if (actualSize != otherSize) {
            throwAssertionError("Expecting size of <%s> to be <%s> but was <%s>", actual, otherSize, actualSize);
        }

        return myself;
    }

    public CustomIterableAssert<T> hasSameSizeAs(CharSequence other) {
        isNotNull();

        int actualSize = 0;
        int otherSize = other.length();

        for (T element : actual) {
            actualSize++;
        }

        if (actualSize != otherSize) {
            throwAssertionError("Expecting size of <%s> to be <%s> but was <%s>", actual, otherSize, actualSize);
        }

        return myself;
    }

    public CustomIterableAssert<T> hasSameSizeAs(byte[] other, Charset charset) {
        isNotNull();

        int actualSize = 0;
        int otherSize = new String(other, charset).length();

        for (T element : actual) {
            actualSize++;
        }

        if (actualSize != otherSize) {
            throwAssertionError("Expecting size of <%s> to be <%s> but was <%s>", actual, otherSize, actualSize);
        }

        return myself;
    }

    public CustomIterableAssert<T> hasSameSizeAs(InputStream other) throws IOException {
        isNotNull();

        int actualSize = 0;
        int otherSize = IOUtils.toByteArray(other).length;

        for (T element : actual) {
            actualSize++;
        }

        if (actualSize != otherSize) {
            throwAssertionError("Expecting size of <%s> to be <%s> but was <%s>", actual, otherSize, actualSize);
        }

        return myself;
    }

    public CustomIterableAssert<T> hasSameSizeAs(Reader other) throws IOException {
        isNotNull();

        int actualSize = 0;
        int otherSize = IOUtils.toCharArray(other).length;

        for (T element : actual) {
            actualSize++;
        }

        if (actualSize != otherSize) {
            throwAssertionError("Expecting size of <%s> to be <%s> but was <%s>", actual, otherSize, actualSize);
        }

        return myself;
    }

    public CustomIterableAssert<T> hasSameSizeAs(File other) throws IOException {
        isNotNull();

        int actualSize = 0;
        int otherSize = FileUtils.sizeOf(other);

        for (T element : actual) {
            actualSize++;
        }

        if (actualSize != otherSize) {
            throwAssertionError("Expecting size of <%s> to be <%s> but was <%s>", actual, otherSize, actualSize);
        }

        return myself;
    }

    public CustomIterableAssert<T> hasSameSizeAs(Path other) throws IOException {
        isNotNull();

        int actualSize = 0;
        int otherSize = (int) Files.size(other);

        for (T element : actual) {
            actualSize++;
        }

        if (actualSize != otherSize) {
            throwAssertionError("Expecting size of <%s> to be <%s> but was <%s>", actual, otherSize, actualSize);
        }

        return myself;
    }

    public CustomIterableAssert<T> hasSameSizeAs(URL other) throws IOException {
        isNotNull();

        int actualSize = 0;
        int otherSize = IOUtils.toByteArray(other).length;

        for (T element : actual) {
            actualSize++;
        }

        if (actualSize != otherSize) {
            throwAssertionError("Expecting size of <%s> to be <%s> but was <%s>", actual, otherSize, actualSize);
        }

        return myself;
    }

    public ThrowableAssert.ThrowingCallable extractThrows(Consumer<T> consumer) {
        return () -> {
            for (T element : actual) {
                consumer.accept(element);
            }
        };
    }
}

在上面的示例中,我们创建了一个名为CustomIterableAssert的自定义断言类,继承自AbstractIterableAssert。该类提供了一系列用于断言可迭代对象的方法,例如containsCustomdoesNotContainCustomhasSize等。这些方法可以根据具体的测试需求进行扩展和定制。

使用自定义断言时,可以通过静态方法assertThat创建一个CustomIterableAssert对象,并使用断言方法进行断言。例如:

代码语言:txt
复制
List<String> list = Arrays.asList("apple", "banana", "orange");
CustomIterableAssert.assertThat(list).containsCustom("apple").hasSize(3);

在上面的示例中,我们使用自定义断言containsCustom断言列表中包含"apple",并使用hasSize断言列表的大小为3。

关于Assertj和自定义断言的更多信息,可以参考腾讯云的相关文档和示例代码:

希望以上信息能够帮助你理解Assertj如何为可迭代对象创建自定义断言。如果还有其他问题,请随时提问。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

帮助 Java 开发人员进行 Bean 映射的 8 大框架

尽管将一个对象映射到另一个对象是很常见的,但由于这两个类具有相似或相同的映射属性,它通常可能是迭代且乏味的。幸运的是,有几个 Java 映射框架可以用来递归地将数据从一个对象复制到另一个对象。...是可变的(即可以在创建后更改),因此它们无法从不可变对象 Java 中的字符串在创建后无法更改)中受益。...只有在该数据映射到其他对象之后。 重映射 ReMap 是一个 Java 映射库,帮助开发人员逐个属性地简化对象转换,同时减少映射器类的单元测试。...BasicPersonDto.class) .field ("name", "fullName" ) .field ("age", "currentAge") .register(); 如果您创建自定义...Mappers、Convertors 和 ObjectFactory 类型,也可以自定义 Orika 映射,其中映射器可用于将对象的属性应用于另一个对象;ObjectFactory 可用于在映射的上下文中构造实例

2.2K10

python小例子(二)

3.python2和python3 range(1000)的区别 python2返回列表,python3返回迭代器 4.什么样的语言可以使用装饰器? 函数可以作为参数传递的语言。...(1)__init__时初始化方法,创建对象后,就立刻被默认调用了,接收参数; (2)__new__必须要有一个参数cls,代表当期类,此参数在实例化时由python解释器自动识别; (3)__new...,那么实际创建返回的就是其他类的实例,其实就是不会调用当前类的__init__函数,也不会调用其他类的__init__函数。..." res=re.findall(tmp,s) print(res) 输出:["中国"] 11.python中断言(assert),断言成功,程序继续运行,断言失败,则程序报错 a=3 assert...(a>1) print(‘断言成功,程序运行到这’) 12.python2和python3的区别?

44510

ECMAScript 的 Iterator Helper 提案正式获得浏览器支持!

异步操作: 在处理异步数据流,读取网络资源时,异步迭代器使得按顺序处理异步事件成为可能。 前端框架和库: 许多现代前端框架和库利用迭代器来处理或渲染列表和组件,提供更高效的数据更新和渲染策略。...如果该对象已经是迭代器的实例,那么这个方法会直接返回它。...如果该对象具有 Symbol.iterator 属性,意味着它是迭代的,那么就会调用它的 Symbol.iterator 方法来获取迭代器,并由此方法返回。...否则,会创建一个新的迭代对象(该对象从 Iterator.prototype 继承并具有 next() 和 return() 方法),该对象包装了这个对象并由此方法返回。...// 从博客存档页面中选择博客文章列表 const posts = document.querySelectorAll('li:not(header li)'); // 首先从帖子中创建一个迭代器。

12810

Python单元测试框架unittest入门

支持测试定制: unittest框架可以轻松集成第三方库,支持创建自定义的测试用例和测试套件。执行结果明确: unittest框架提供了详细的错误信息,让测试人员能够快速地定位和修复错误。...这些方法可以在测试类中重写,并根据需要进行自定义操作。...创建一个unittest.TestSuite对象,并将加载的测试用例添加到测试套件中。你可以使用addTest()方法添加单个测试用例,或者使用addTests()方法添加多个测试用例。...创建一个unittest.TextTestRunner对象。调用run()方法运行测试套件,并将结果输出到控制台或文件中。...(x)断言x为TrueassertFalse(x)断言x为FalseassertIs(a, b)断言a和b是同一个对象assertIsNot(a, b)断言a和b不是同一个对象assertIsNone(

40120

忘了打印测试吧,JUnit 真香!

何为测试 在计算机领域中,所谓测试,描述的是一种用来鉴定软件正确性、完整性和质量的过程。而软件测试又一般可以分为黑盒测试和白盒测试,两者的相关定义如下。...在我们简单的小程序中,平常测试使用的方法是在主类中创建对象,然后调用对应方法。...测试成功的界面 测试失败的界面 总结起来,我们针对一个方法的具体测试的步骤如下: 首先是创建被测试类的对象; 然后调用被测试的方法; 最后加入断言,判断调用方法得到结果和实际的结果之间是否相同;...标记和过滤 而相对于 Junit4,Junit5 也有做出升级,其特有的一些注解如下: 注解 说明 @TestFactory 测试工厂进行动态测试 @Nested 嵌套测试 @ExtendWith 注册自定义扩展...常用断言方法 而在测试中,我们经常用到断言方法。

42530

还在通过注释代码来进行功能测试?那你需要看看这份 Junit 单元测试指南

已收录至博客 https://cunyu1943.blog.csdn.net,建议关注后续修改更新 ~ 何为测试 在计算机领域中,所谓测试,描述的是一种用来鉴定软件正确性、完整性和质量的过程。...在我们简单的小程序中,平常测试使用的方法是在主类中创建对象,然后调用对应方法。...总结起来,我们针对一个方法的具体测试的步骤如下: 首先是创建被测试类的对象; 然后调用被测试的方法; 最后加入断言,判断调用方法得到结果和实际的结果之间是否相同; JUnit 常用注解 由于现在主要用到的有...标记和过滤 而相对于 Junit4,Junit5 也有做出升级,其特有的一些注解如下: 注解 说明 @TestFactory 测试工厂进行动态测试 @Nested 嵌套测试 @ExtendWith 注册自定义扩展...常用断言方法 而在测试中,我们经常用到断言方法。

77340

论python中器的组合

python中有几种特殊的对象迭代对象、生成器、迭代器、装饰器等等,特别是生成器这些可以说是python中的门面担当,应用好这些特性的话,可以给我们的项目带来本质上的提升,装逼不说,这构筑的是代码护城河...迭代对象通过 __iteration__提供一个迭代器,在迭代一个迭代对象的时候,实际上就是先获取该对象提供的迭代器,然后通过这个迭代器来以此获取对象中的每一个数据,这也是一个具备__iter__方法的对象...对所有的迭代对象调用dir() 方法时,会发现他们都默认实现了__iter__ 方法。我们可以通过iter(object) 来创建一个迭代器。...我们不妨断言所有实现了__iter__ 和__next__ 两个方法的对象,都是迭代器。...总结 容器是一系列元素的集合,str、list、set、dict、file、sockets对象都可以看作是容器,容器都可以被迭代(用在for,while等语句中),因此他们被称为迭代对象

68030

从ES6到ES10的新特性万字大总结(不得不收藏)

(包括 Array,Map,Set,String,TypedArray,arguments 对象等等)上创建一个迭代循环,调用自定义迭代钩子,并为每个不同属性的值执行语句。...一旦创建迭代对象可以通过重复调用next()显式地迭代,从而获取该对象每一级的值,直到迭代完,返回{ value: undefined, done: true } 虽然自定义迭代器是一个有用的工具...Object.getOwnPropertyDescriptors({ // 在这里定义方法和属性 })) ES9(ES2018) for await...of for await...of 语句会在异步或者同步迭代对象创建一个迭代循环...,包括 String,Array,Array-like 对象(比如arguments 或者NodeList),TypedArray,Map, Set和自定义的异步或者同步迭代对象。...其会调用自定义迭代钩子,并为每个不同属性的值执行语句。

2.1K20

《重构》第九章 - 读后感(简化条件表达式)

何为条件表达式?很明显这里讲的应该表达的是if语句的问题。那么if语句在我们编程过程中肯定是用的不规范,或者说有违背我们开头所说的自己管好自己的基本原则。...相当于说对于特殊的复杂的判断语句就不要往if中迭代了,直接新做一个判断语句并独立出来。...但是使用直接判断一个对象是否为null的问题是什么?为啥这种模式不太好?书中写到要判断一个对象是否为null,那么就意味着重新创建对象。而重新创建对象就又是赋值操作。...所以说这块引入null对象就是为了避免显式的创建对象,除此之外如果是用==去判断是否为null,就会导致一个对象在项目的很多地方存在,如果需要变化是不好处理的。...如果我们不去显式创建对象,那么就需要在判断 之后进行隐式的创建对象了,也就是赖加载的模式。我们通过空对象去继承原类,然后重新写对其为空的各种情况进行给定默认值。

25210

【单元测试】--工具与环境

以下是一些关键特点和概念,来介绍 JUnit: 注解和断言: JUnit 使用注解( @Test)来标识测试方法,并使用断言 assertEquals)来验证代码的行为是否符合预期。...断言库: JUnit 4+版本引入了 Hamcrest 断言库,允许更灵活和自定义断言。 异常测试: JUnit 允许测试方法声明预期抛出的异常,以确保代码在错误情况下正确处理异常。...通常,你可以使用第三方库, Moq、NSubstitute 或 Rhino Mocks,来创建模拟和存根对象。以下是使用 Moq 作为示例的步骤: 1....创建存根对象: 在单元测试中,首先创建一个存根对象,它将代替真实的外部依赖。...运行测试: 运行测试用例,以确保被测对象与存根对象一起协作,并产生正确的结果。 使用模拟和存根有助于隔离被测代码,使测试更加独立和重复。这种方法允许你测试代码的特定行为,而不依赖于外部依赖的状态。

33050

Junit | 不会写单元测试,就如同不穿秋裤的熊孩子在冬天瞎跑

assertNotEquals 断言传入的预期值与实际值是不相等的 assertArrayEquals 断言传入的预期数组与实际数组是相等的 assertNull 断言传入的对象是为空 assertNotNull...断言传入的对象是不为空 assertTrue 断言条件为真 assertFalse 断言条件为假 assertSame 断言两个对象引用同一个对象,相当于“==” assertNotSame 断言两个对象引用不同的对象...* * 解法思路: * 使用栈存储,将字符串切割为char遍历,先存储指定方向的符号,'(','{','['。...首先需要在测试类上添加 RunWith(Paramterized.class) 注解,在创建一个由 @Paramters 注解的 static 方法,让返回一个对应的测试数据合集,最后创建构造方法,方法的参数顺序和测试数据集合一一对应...)); hasItem 断言迭代对象含有此元素 assertThat(list, hasItem(element)); @Rule 在测试过程中,我们也可以通过增加 @Before 或者 @After

73650

GTEST学习总结

2.2.3String comparison 2.3创建测试用例 2.4TestFixtures 2.5更多断言方法 2.6异常断言 2.7自定义输出语句 2.8谓词断言 pred 2.9AssertionResult...2.3创建测试用例 创建一个测试用例(TEST): 1.使用锚 TEST() 2.函数体支持C++语句 3.测试结果的成功与否与断言语句有关。...只要有一条断言失败,者是测试崩了,那么这个测试用例就算是失败的。...使用protected 启动它的主体,因为我们需要从子类访问fixture的成员 2.在类中,声明需要使用的对象 3.如有必要,写一个默认的构造函数 或 SetUp() 方法 用来 为每个测试准备对象...发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

67430

软件测试之 自动化测试 基于Python语言使用Selenium、ddt、unitTest 实现自动化测试

assertIn(a, b) a 和 b 可以是迭代对象,其中 a 是 b 的一个元素。 检查 a 是否在 b 中存在。...assertNotIn(a, b) a 和 b 可以是迭代对象,其中 a 不是 b 的一个元素。 检查 a 是否不在 b 中存在。...assertIsNotNone(x) x 可以是任何对象,用于检查它是否不为 None。 检查 x 是否不为 None。 迭代对象是指能够被迭代遍历的数据结构,通常是包含多个元素的集合。...文件对象(File Object):可以逐行读取文件内容。 迭代器(Iterator):自定义迭代对象,通过实现 __iter__() 和 __next__() 方法来支持迭代。...相当于给文件对象或其他对象起一个“别名” wb和w模式打开文件有以下区别: w模式: 以文本写入模式打开文件,如果文件不存在则创建,如果文件存在则将其内容清空后再写入。

8210

干货 | 提前在开发阶段暴露代码问题,携程Alchemy代码质量平台

一、背景 随着敏捷开发,DevOps开发模式的流行,代码质量分析作为研发质量保证体系的重要组成部分,不仅能有效的降低因频繁迭代带来的故障风险,而且对整个工程团队的效能提升有着巨大的价值。...扫描分析结果可以在Gitlab或者Alchemy平台上展示,帮助开发人员在快速迭代的同时保证代码质量。...在实际应用中,针对封装的判空方法,通过添加@TrueOnNull或@FalseOnNull注解,识别对象的判空操作。...重复代码详情结果 4.4 自定义规则扫描 Alchemy支持对自定义规则的扫描,通过配置自定义正则表达式和扫描范围,识别代码文件中满足配置规则的代码段,可用于扫描代码中的拼接SQL,敏感词等,并且可将不合规的代码定位到相关开发人员...代码分析结果 4.6 代码搜索 在开发过程中,对于一些公共操作中间件的使用方式,开发人员可能需要四处寻找接入文档。

1.7K10
领券