ExtentReports使用过程中遇到的MongoDB坑是怎样的

发布时间:2021-09-29 11:41:05 作者:柒染
来源:亿速云 阅读:152
# ExtentReports使用过程中遇到的MongoDB坑是怎样的

## 引言

在自动化测试领域,ExtentReports作为一款强大的测试报告生成工具,因其丰富的可视化效果和灵活的扩展性被广泛使用。当它与MongoDB这类NoSQL数据库结合时,可以实现历史报告存储、多维度分析等高级功能。但在实际集成过程中,开发者往往会遇到各种意料之外的"坑"。本文将详细剖析这些典型问题及其解决方案。

## 一、环境配置陷阱

### 1.1 驱动版本兼容性问题

```java
// 典型报错示例
NoSuchMethodError: com.mongodb.client.MongoCollection.insertOne(Lorg/bson/conversions/Bson;)

问题原因
ExtentReports的MongoDB适配器可能依赖较旧版本的Mongo Java驱动(如3.x),而项目实际引入的是新版本(4.x+),导致API不兼容。

解决方案: 1. 查看ExtentReports官方文档确认兼容的驱动版本 2. 在pom.xml中显式指定驱动版本:

<dependency>
    <groupId>org.mongodb</groupId>
    <artifactId>mongo-java-driver</artifactId>
    <version>3.12.10</version> <!-- 与ExtentReports兼容的版本 -->
</dependency>

1.2 认证协议变更

MongoDB 4.0+默认使用SCRAM-SHA-256认证,而旧版ExtentReports可能仅支持SCRAM-SHA-1:

Exception authenticating MongoCredential{
  mechanism=SCRAM-SHA-1, 
  userName='user', 
  source='admin', 
  password=<hidden>, 
  mechanismProperties=<hidden>
}

解决方法: 1. 在MongoDB服务端启用双认证协议:

   mongod --auth --setParameter authenticationMechanisms=SCRAM-SHA-1,SCRAM-SHA-256
  1. 或升级ExtentReports到支持新认证协议的版本

二、数据结构冲突

2.1 默认_id字段冲突

当同一份测试报告多次写入时,会因重复的ObjectId导致报错:

E11000 duplicate key error collection: test.reports index: _id_ dup key: { _id: ObjectId('5f3d7b...') }

解决方案: 自定义Reporter配置,禁用自动生成_id:

ExtentMongoReporter reporter = new ExtentMongoReporter(
    MongoClients.create("mongodb://localhost:27017"),
    "test",
    "reports"
);

reporter.config().setAutoGenerateObjectId(false); // 关键配置

2.2 BSON文档大小限制

单个测试报告包含大量截图时,可能超过MongoDB默认16MB文档限制:

BSONObjectTooLarge: The document exceeds maximum allowed BSON object size

应对策略: 1. 启用GridFS存储大文件:

   GridFSBucket gridFS = GridFSBuckets.create(database);
   gridFS.uploadFromStream("screenshot.png", inputStream);
  1. 拆分报告结构,将附件单独存储
  2. 调整MongoDB服务端配置(不推荐)

三、连接管理缺陷

3.1 连接泄漏问题

未正确关闭MongoClient会导致连接池耗尽:

// 错误示例
@AfterSuite
public void tearDown() {
    // 忘记关闭client
}

正确做法

MongoClient client = MongoClients.create(uri);

@AfterSuite
public void tearDown() {
    if(client != null) {
        client.close(); // 显式释放连接
    }
}

3.2 集群配置敏感

当使用副本集时,初级配置容易导致主节点切换后连接失败:

// 脆弱配置
String uri = "mongodb://primary:27017";

// 健壮配置
String uri = "mongodb://node1:27017,node2:27017,node3:27017/?replicaSet=rs0";

四、性能优化难点

4.1 批量插入性能低下

逐条插入报告数据会导致性能瓶颈:

// 低效写法
for(Test test : tests) {
    collection.insertOne(convertToDocument(test));
}

优化方案

List<Document> batch = new ArrayList<>();
for(Test test : tests) {
    batch.add(convertToDocument(test));
    if(batch.size() >= 100) {
        collection.insertMany(batch);
        batch.clear();
    }
}
if(!batch.isEmpty()) {
    collection.insertMany(batch);
}

4.2 索引缺失导致查询缓慢

未针对常用查询字段建立索引时,历史报告检索会异常缓慢:

// 典型查询场景
db.reports.find({ "testName": "loginTest" }).sort({ "startTime": -1 })

优化建议

// 建立复合索引
db.reports.createIndex({ 
    "testName": 1, 
    "startTime": -1 
})

五、事务支持限制

5.1 多文档事务问题

ExtentReports默认实现不支持MongoDB 4.0+的多文档事务:

// 伪代码示例
try {
    client.startSession();
    // 报告写入操作1...
    // 报告写入操作2...
    session.commitTransaction();
} catch(Exception e) {
    session.abortTransaction();
}

应对方案: 1. 对于关键业务,考虑实现自定义的TransactionalReporter 2. 或采用MongoDB 4.2+的retryWrites机制

六、监控与维护挑战

6.1 报告数据无限增长

未设置TTL索引会导致存储空间被快速耗尽:

// 解决方案:创建自动过期索引
db.reports.createIndex(
    { "createdAt": 1 },
    { expireAfterSeconds: 2592000 } // 30天后自动删除
)

6.2 分片策略不当

当报告数据量达到TB级时,需要合理设计分片键:

sh.enableSharding("test")
sh.shardCollection("test.reports", { "project": 1, "date": 1 })

结语

与MongoDB集成确实能让ExtentReports如虎添翼,但每个技术决策都需要权衡利弊。建议在实际项目中: 1. 严格进行版本控制 2. 实施完善的异常处理 3. 建立性能基准测试 4. 制定定期的维护计划

只有充分理解这些潜在问题,才能构建出稳定可靠的测试报告系统。希望本文的实践经验能帮助开发者少走弯路。 “`

注:本文示例代码基于ExtentReports 5.x和MongoDB Java Driver 3.12版本,实际实现可能因版本差异需要调整。建议读者结合官方文档和具体环境进行验证。

推荐阅读:
  1. hadoop遇到的坑
  2. addView遇到的坑及其解决

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

mongodb

上一篇:如何分析Discuz7.2版的faq.php SQL注入漏洞

下一篇:如何理解ASP.NET MVC5网站开发框架模型、数据存储、业务逻辑

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》