在线音乐服务器测试报告

一、项目背景

       在线音乐服务器采用前后端分离的方法来实现,同时使用了数据库来存储相关的数据,同时将其部署到云服务器上。前端主要有个页面构成:登录页、音乐列表页、收藏音乐页等,以上模拟实现了最简单的在线音乐服务器。其结合后端实现了以下的主要功能:登录、上传音乐、播放音乐、查询音乐、删除音乐、收藏音乐、取消收藏音乐等功能。该音乐服务器可以实现用户简单的听音乐,收藏音乐等需求。

二、项目功能

       在线音乐服务器主要实现了以下几个功能:登录、上传音乐、播放音乐、查询音乐、删除音乐、收藏音乐、取消收藏音乐等功能。

  1. 登录功能:用户输入用户名和密码,如果输入正确的用户名和密码则登录成功并跳转到个人博客列表页面;如果输入错误的用户名和密码则提示用户输入的信息有误,登录失败。

  2. 上传音乐功能:用户上传格式正确的音乐文件,以及填写音乐所属的歌手名,最终能成功上传到服务器保存。

  3. 播放音乐功能:用户点击播放音乐,音乐能够正常播放。

  4. 查询音乐功能:用户可以通过模糊查询和精确查询所要想搜索的音乐。

  5. 删除音乐功能:用户可以单个删除音乐,也可以通过勾选批量删除多个音乐。

  6. 收藏音乐功能:用户选择喜欢的音乐可进行收藏,成功收藏后可保存在个人收藏列表页。

  7. 展示收藏音乐功能:展示用户收藏的喜欢的音乐,并且能够进行正常的播放等操作。

  8. 取消收藏音乐功能:用户在收藏音乐的列表中可以选择删除取消收藏的音乐。

三、Web自动化测试

一)测试用例设计
在这里插入图片描述

二)代码编写

  1. 登录功能测试
    ① 创建驱动,并打开页面;
    ② 测试页面是否正常打开;
    ③ 测试正常登录:使用正确的用户名和密码进行等;
    ④ 测试异常登录:用户名/密码不正确,登录失败,多参数测试;
    ⑤ 注意测试的顺序,使用Order注解指定,否则可能会因为执行顺序不对导致测试失败;
    ⑥ 注意清空内容后才能再次输入用户名、密码。
package com.musicAutoTest.Tests;import com.musicAutoTest.common.AutotestUtils;
import org.junit.jupiter.api.*;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.chrome.ChromeDriver;import java.time.Duration;@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class LoginTest extends AutotestUtils {private static ChromeDriver driver = createDriver();@BeforeAllstatic void baseControl() {driver.get("http://localhost:8888/login.html");}/*** 页面可以正常显示*/@Test@Order(1)void LoginLoadRight() {driver.findElement(By.cssSelector("#body > div > div:nth-child(3) > label"));driver.findElement(By.cssSelector("#body > div > div.alert.alert-warning.alert-dismissible"));}/*** 正常登录*/@Test@Order(3)void LoginSuc() throws InterruptedException {driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3));driver.findElement(By.cssSelector("#user")).clear();driver.findElement(By.cssSelector("#password")).clear();driver.findElement(By.cssSelector("#user")).sendKeys("shuai");driver.findElement(By.cssSelector("#password")).sendKeys("123456");driver.findElement(By.cssSelector("#submit")).click();Thread.sleep(5);Alert alert = driver.switchTo().alert();alert.accept();//检查是否登录成功driver.findElement(By.cssSelector("#body > div.container > h3"));driver.findElement(By.cssSelector("#body > div.container > div:nth-child(3) > a:nth-child(1)"));driver.navigate().back();}/*** 异常登录*/@ParameterizedTest@Order(2)@CsvSource({"'',''","'',123","'',123","123,123"})void LoginFail(String name, String password) throws InterruptedException {driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3));driver.findElement(By.cssSelector("#user")).clear();driver.findElement(By.cssSelector("#password")).clear();driver.findElement(By.cssSelector("#user")).sendKeys(name);driver.findElement(By.cssSelector("#password")).sendKeys(password);driver.findElement(By.cssSelector("#submit")).click();Thread.sleep(5);Alert alert = driver.switchTo().alert();alert.accept();//检查是否登录没成功driver.findElement(By.cssSelector("#body > div > div:nth-child(3) > label"));driver.findElement(By.cssSelector("#body > div > div.alert.alert-warning.alert-dismissible"));}
}
  1. 上传音乐功能测试
    ① 如若驱动已经创建好则不需再次创建驱动,打开页面;
    ② 测试页面是否正常打开;
    ③ 正常的上传,上传正确格式的音乐文件;
    ④ 测试异常上传:上传非音乐格式的文件。
package com.musicAutoTest.Tests;import com.musicAutoTest.common.AutotestUtils;
import org.junit.jupiter.api.*;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;import java.time.Duration;
import java.util.List;@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class UploadMusicTest extends AutotestUtils {private static ChromeDriver driver = createDriver();@BeforeAllstatic void baseControl() {driver.get("http://localhost:8888/list.html");}/*** 检查页面能否正常打开*/@Test@Order(1)void pageLoadRight() {driver.findElement(By.cssSelector("#body > div.container > h3"));driver.findElement(By.cssSelector("#body > div.container > div:nth-child(3)"));}/*** 上传音乐*/@Test@Order(2)void uploadSuc() {driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3));List<WebElement> list1 = driver.findElements(By.name("tr"));int count1 = list1.size();driver.findElement(By.cssSelector("#body > div.container > div:nth-child(3) > a:nth-child(2)")).click();driver.findElement(By.cssSelector("body > form > input[type=file]:nth-child(1)")).sendKeys("C:/music.mp3");driver.findElement(By.cssSelector("body > form > label > input[type=text]")).sendKeys("user");driver.findElement(By.cssSelector("body > form > input[type=submit]:nth-child(3)")).click();List<WebElement> list2 = driver.findElements(By.name("tr"));int count2 = list2.size();int suc = count2 - count1;Assertions.assertEquals("1",suc+"");}}
  1. 播放音乐功能测试
    ① 如若驱动已经创建好则不需再次创建驱动,打开页面;
    ② 测试页面是否正常打开;
    ③ 点击播放音乐按钮;
    ④ 测试音乐是否播放,检查点为属性值。
package com.musicAutoTest.Tests;import com.musicAutoTest.common.AutotestUtils;
import org.junit.jupiter.api.*;
import org.openqa.selenium.By;
import org.openqa.selenium.chrome.ChromeDriver;@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class RunMusicTest extends AutotestUtils {private static ChromeDriver driver = createDriver();//打开页面@BeforeAllstatic void baseControl() {driver.get("http://localhost:8888/list.html");}//页面能否正常显示@Test@Order(1)void pageLoadRight() {driver.findElement(By.cssSelector("#body > div.container > h3"));driver.findElement(By.cssSelector("#body > div.container > div:nth-child(3)"));}//能否正常播放音乐@Test@Order(2)void runMusicSuc() {driver.findElement(By.cssSelector("#info > tr:nth-child(1) > td:nth-child(4) > button")).click();//检查点,属性值String text = driver.findElement(By.cssSelector("#body > div:nth-child(2) > div > div > div.controlbar > ul > li:nth-child(1) > a")).getAttribute("style");System.out.println(text);Assertions.assertEquals("display: none;",text);}}
  1. 查询音乐功能
    ① 如若驱动已经创建好则不需再次创建驱动,打开页面;
    ② 测试页面是否正常打开;
    ③ 输入空字符进行查询;
    ④ 分别进行模糊查询和精确查询测试是否能查询到。
package com.musicAutoTest.Tests;import com.musicAutoTest.common.AutotestUtils;
import org.junit.jupiter.api.*;
import org.openqa.selenium.By;
import org.openqa.selenium.chrome.ChromeDriver;import java.time.Duration;@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class SelectMusicTest extends AutotestUtils {private static ChromeDriver driver = createDriver();//打开页面@BeforeAllstatic void baseControl() {driver.get("http://localhost:8888/list.html");}//页面能否正常显示@Test@Order(1)void pageLoadRight() {driver.findElement(By.cssSelector("#body > div.container > h3"));driver.findElement(By.cssSelector("#body > div.container > div:nth-child(3)"));}//精确查询@Test@Order(2)void searchOne() {driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3));driver.findElement(By.cssSelector("#exampleInputName2")).clear();driver.findElement(By.cssSelector("#exampleInputName2")).sendKeys("music");driver.findElement(By.cssSelector("#submit1")).click();String text = driver.findElement(By.cssSelector("#info > tr > td:nth-child(2)")).getText();Assertions.assertEquals("music",text);}//模糊查询@Test@Order(3)void searchMore() {driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3));driver.findElement(By.cssSelector("#exampleInputName2")).clear();driver.findElement(By.cssSelector("#exampleInputName2")).sendKeys("mu");driver.findElement(By.cssSelector("#submit1")).click();String text = driver.findElement(By.cssSelector("#info > tr > td:nth-child(2)")).getText();Assertions.assertEquals("music",text);}
}
  1. 收藏音乐功能
    ① 如若驱动已经创建好则不需再次创建驱动,打开页面;
    ② 测试页面是否正常打开;
    ③ 点击收藏音乐,测试是否被收藏。
package com.musicAutoTest.Tests;import com.musicAutoTest.common.AutotestUtils;
import org.junit.jupiter.api.*;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.chrome.ChromeDriver;@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class LoveMusicTest extends AutotestUtils {private static ChromeDriver driver = createDriver();//打开页面@BeforeAllstatic void baseControl() {driver.get("http://localhost:8888/list.html");}//页面能否正常显示@Test@Order(1)void pageLoadRight() {driver.findElement(By.cssSelector("#body > div.container > h3"));driver.findElement(By.cssSelector("#body > div.container > div:nth-child(3)"));}//点击喜欢@Test@Order(2)void loveMusicSuc() throws InterruptedException {driver.findElement(By.cssSelector("#info > tr:nth-child(1) > td:nth-child(5) > button:nth-child(2)")).click();Thread.sleep(5);Alert alert = driver.switchTo().alert();String text = alert.getText();alert.accept();Assertions.assertEquals("加入喜欢的列表成功",text);}//重复点击@Test@Order(3)void loveMusicFail() throws InterruptedException {driver.findElement(By.cssSelector("#info > tr:nth-child(1) > td:nth-child(5) > button:nth-child(2)")).click();Thread.sleep(8);Alert alert = driver.switchTo().alert();String text = alert.getText();alert.accept();Assertions.assertNotEquals("加入喜欢的列表成功",text);}}
  1. 展示收藏音乐列表功能
    ① 如若驱动已经创建好则不需再次创建驱动,打开页面;
    ② 测试页面是否正常打开;
    ③ 测试刚收藏的音乐是否再列表中展示。
package com.musicAutoTest.Tests;import com.musicAutoTest.common.AutotestUtils;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.chrome.ChromeDriver;public class ShowLoveMusicTest extends AutotestUtils {private static ChromeDriver driver = createDriver();@BeforeAllstatic void baseControl() {driver.get("http://localhost:8888/loveMusic.html");}/*** 展示收藏的音乐列表*/@Testvoid showSuc() {String text = driver.findElement(By.cssSelector("#info > tr > td:nth-child(2)")).getText();Assertions.assertEquals("music",text);}}
  1. 取消收藏音乐功能
    ① 如若驱动已经创建好则不需再次创建驱动,打开页面;
    ② 测试页面是否正常打开;
    ③ 点击取消收藏音乐,检查音乐是否已经被移除收藏列表。
package com.musicAutoTest.Tests;import com.musicAutoTest.common.AutotestUtils;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;import java.util.List;public class DeleteLoveMusicTest extends AutotestUtils {private static ChromeDriver driver = createDriver();@BeforeAllstatic void baseControl() {driver.get("http://localhost:8888/loveMusic.html");}/*** 取消收藏的音乐*/@Testvoid deleteLoveMusic() {List<WebElement> list = driver.findElements(By.name("#tr"));int count1 = list.size();driver.findElement(By.cssSelector("#info > tr > td:nth-child(5) > button")).click();//统计数量List<WebElement> list2 = driver.findElements(By.name("tr"));int count2 = list2.size();//再统计数量int suc = count1 - count2;Assertions.assertEquals("1",suc+"");}}
  1. 删除音乐功能
    ① 如若驱动已经创建好则不需再次创建驱动,打开页面;
    ② 测试页面是否正常打开;
    ③ 点击删除音乐,检查音乐是否被删除。
package com.musicAutoTest.Tests;import com.musicAutoTest.common.AutotestUtils;
import org.junit.jupiter.api.*;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;import java.util.List;@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class DeleteMusicTest extends AutotestUtils {private static ChromeDriver driver = createDriver();@BeforeAllstatic void baseControl() {driver.get("http://localhost:8888/loveMusic.html");}/*** 删除音乐*/@Testvoid deleteMusic() {List<WebElement> list = driver.findElements(By.name("#tr"));int count1 = list.size();driver.findElement(By.cssSelector("#info > tr:nth-child(1) > td:nth-child(5) > button:nth-child(1)")).click();//统计数量List<WebElement> list2 = driver.findElements(By.name("tr"));int count2 = list2.size();//再统计数量int suc = count1 - count2;Assertions.assertEquals("1",suc+"");}
}
  1. 屏幕截图
    /*** 动态生成时间*/public List<String> getTime() {//文件夹按照天的维度进行保存//文件格式 20240109-123030SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat("yyyyMMdd-HHmmssSS");SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("yyyyMMdd");String filename = simpleDateFormat1.format(System.currentTimeMillis());String dirname = simpleDateFormat2.format(System.currentTimeMillis());List<String> list = new ArrayList<>();list.add(dirname);list.add(filename);return list;}/*** 获取屏幕截图,把所有的测试用例执行的结果保存下来*/public void getScreenShor(String str) throws IOException {List<String> list = getTime();//dir+filename// ./src/test/java/com/blogWebAutoTest/dirname/filenameString fileName = "./src/test/java/com/blogWebAutoTest/"+list.get(0) + "/" + str + "-" + list.get(1) + ".png";File srcfile = driver.getScreenshotAs(OutputType.FILE);//把屏幕截图生成的文件放到指定的路径FileUtils.copyFile(srcfile,new File(fileName));String filename = "my";}

三)代码测试
在这里插入图片描述

四、总结

  1. 使用了Junit5中提供的注解:避免生成过多的对象,造成资源和时间的浪费,提高了自动化的执行效率。
  2. 只创建一次驱动对象,避免每个用例重复创建驱动对象造成时间和资源的浪费。
  3. 使用参数化:保持用例的简洁,提高代码的可读性。
  4. 使用测试套件:降低了测试人员的工作量,通过套件一次执行所有要运行的测试用例。
  5. 使用了等待:提高了自动化的运行效率,提高了自动化的稳定性,减小误报的可能性。
  6. 使用了屏幕截图:方便问题的追溯以及问题的解决。
  7. 使用了无头模式:只注重结果,可以留出屏幕。

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

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

相关文章

【深入浅出MySQL】「底层原理」InnoDB索引原理全程实操指南,带你从入门到精通

InnoDB索引原理全程实操指南&#xff0c;带你从入门到精通 每日一句前言概述正文介绍索引的介绍创建索引聚集索引非聚集索引**如果我的表没有建立主键该怎么办呢&#xff1f;** 索引原理什么情况不去聚集索引树去查询&#xff1f;版权声明 每日一句 不要停顿,因为别人会超过你;…

机器学习 | 揭示EM算法和马尔可夫链的实际应用

目录 初识EM算法 马尔可夫链 HMM模型基础 HMM模型使用 初识EM算法 EM算法是一种求解含有隐变量的概率模型参数的迭代算法。该算法通过交替进行两个步骤&#xff1a;E步骤和M步骤&#xff0c;从而不断逼近模型的最优参数值。EM算法也称期望最大化算法&#xff0c;它是一个基…

机器学习——流形学习

流形学习是一种在机器学习领域中用于理解和分析数据的技术。它的核心思想是&#xff0c;尽管我们通常将数据表示为高维空间中的向量&#xff0c;但实际上数据可能具有较低维度的内在结构&#xff0c;这种结构被称为流形。流形学习的目标是发现并利用数据的这种潜在结构&#xf…

H12-821_28

28.如图所示,在一个纯IPv6环境中,若想实现PC1与PC2之间的通信,下列哪组地址可以分别配置在PC1与P2上 A.2001:FDC:1/64 2001:FDC::2/64 B.2001:FDC::1/64 2001:FDC1::2/64 C.FD00:1AC0:872E::1/64 FD00:2BE1:2320::1/64 D.FE80::1/64 FE80::2/64 答案&#xff1a;B 注释&…

图数据库 之 Neo4j - 背景介绍(1)

引言 Neo4j是一种高性能的图数据库&#xff0c;它专门设计用于存储、管理和查询大规模的图数据。与传统的关系型数据库不同&#xff0c;Neo4j以图的形式存储数据&#xff0c;其中节点表示实体&#xff0c;边表示实体之间的关系。这种图数据模型非常适合表示复杂的关系和连接。…

Termux配置安卓编译环境

前言 Termux安装后&#xff0c;就相当于把手机变成了一台Linux服务器&#xff0c;而且现在手机卡通常是能拿到ipv6公网地址的&#xff0c;所以&#xff0c;这个服务器能干啥&#xff1f; 编程搭建网站跑脚本 本文讲述的就是怎么在Termux搭建安卓编译环境&#xff0c;实现手机…

GraphicsMagick 的 OpenCL 开发记录(三十二)

文章目录 如何写ScaleImage()的硬件加速函数&#xff08;六&#xff09; <2022-04-27 周三> 如何写ScaleImage()的硬件加速函数&#xff08;六&#xff09; 不管什么事儿看来都怕琢磨&#xff0c;如果连做梦都能梦到你正在琢磨的事儿&#xff0c;估计离成功也就不远了。…

c++之说_12|模板

关于模板&#xff0c;至少我们要先了解几个概念 一&#xff1a;函数模板 二&#xff1a;类模板 三&#xff1a;模板特化 四&#xff1a;形参参数包 模板覆盖的东西太多 我目前也不了解太多 函数模板 语法 template<typename 类型名,typename 类型名,typename ...多参…

【JavaScript学习路线——详细讲解】

JavaScript学习路线 1. 介绍2. JavaScript基础3. HTML/CSS与JavaScript结合4. 进阶JavaScript5. 前端框架与库6. API与HTTP通信7. 移动端和PWA8. Node.js和后端开发9. 测试和部署10. 全栈项目实践11. 持续学习和社区参与 1. 介绍 学习JavaScript的路线可以分为几个主要阶段&am…

【水文】计算斐波那契数列的第n项

#include <stdio.h> // 函数声明 int fibonacci(int n); int main() { // 输入正整数n int n; printf("请输入一个正整数 n&#xff1a;"); scanf("%d", &n); // 调用函数计算斐波那契数列的第n项并输出结果 int result …

CopyOnWriteArrayList底层原理全面解析【建议收藏】

简介 CopyOnWriteArrayList是Java中的一个线程安全的集合类&#xff0c;是ArrayList线程安全版本&#xff0c;主要通过Copy-On-Write&#xff08;写时复制&#xff0c;简称COW&#xff09;机制来保证线程安全。 Copy-On-Write机制核心思想&#xff1a;向一个数组中添加数据时…

LabVIEW动平衡测试与振动分析系统

LabVIEW动平衡测试与振动分析系统 介绍了利用LabVIEW软件和虚拟仪器技术开发一个动平衡测试与振动分析系统。该系统旨在提高旋转机械设备的测试精度和可靠性&#xff0c;通过精确测量和分析设备的振动数据&#xff0c;以识别和校正不平衡问题&#xff0c;从而保证机械设备的高…

Leetcode 322 零钱兑换

题意理解&#xff1a; 给你一个整数数组 coins &#xff0c;表示不同面额的硬币&#xff1b;以及一个整数 amount &#xff0c;表示总金额。 计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额&#xff0c;返回 -1 。 你可以认为每种硬币…

Springboot集成jasypt实现配置文件加密

Jasypt它提供了单密钥对称加密和非对称加密两种加密方式。 单密钥对称加密&#xff1a;一个密钥加盐&#xff0c;可以同时用作内容的加密和解密依据&#xff1b; 非对称加密&#xff1a;使用公钥和私钥两个密钥&#xff0c;才可以对内容加密和解密&#xff1b; 我们以单密钥对称…

前端 reduce()用法总结

定义 reduce()方法对数组中的每个元素执行一个由您提供的reducer函数(升序执行)&#xff0c;将其结果汇总为单个返回值。语法为&#xff1a; array.reduce(function(accumulator, currentValue, currentIndex, arr), initialValue); /*accumulator: 必需。累计器currentValu…

5 步轻松上手,教你从 0 到 1 落地 Jmeter 接口自动化脚本!

Jmeter是进行接口测试的一款非常主流的工具&#xff0c;但绝大部分测试工程师&#xff0c;对于Jmeter接口测试脚本整理都是一知半解的。今天这篇文章&#xff0c;就以一个金融项目中接口为例&#xff0c;通过简单5步&#xff0c;教大家如何0代码编写Jmeter接口自动化脚本&#…

CPU和GPU有什么区别,玩游戏哪个更重要?

大家好&#xff01;今天我们要聊的话题是CPU和GPU&#xff0c;它们在电脑中扮演着重要的角色&#xff0c;虽然看起来只是两个简单的缩写&#xff0c;但它们的功能和影响是截然不同的&#xff01; 那么&#xff0c;究竟CPU和GPU有什么区别呢&#xff1f;在玩游戏时&#xff0c;…

Linux 系统开启网络服务

首先&#xff0c;大家新装的linux系统可能都没有安装vim工具&#xff0c;所以打开文件的方式是 vi /etc/sysconfig/network-scripts/ifcfg-ens33在这个界面把onboot改为yes&#xff0c;我这里是设置完的。然后通过下面语句重新启动服务就可以了。 service network restartcen…

2024.2.7日总结(小程序开发4)

页面导航 页面导航是页面之间的相互跳转&#xff1a; <a>链接location.href 小程序中实现页面导航的两种方式&#xff1a; 声明式导航 在页面上声明一个<navigator>导航组件通过点击<navigator>组件实现页面跳转 编程式导航 调用小程序的导航API&…

飞天使-k8s知识点15-kubernetes散装知识点4-CNI网络插件与kubectl

文章目录 CNI 网络插件安装任意节点运行kubectlAPI的版本区别与废弃API查询 CNI 网络插件安装 这里将以 Calico 为例&#xff0c;提供在 Kubernetes 1.20.6 版本上安装 CNI 插件的步骤。请注意&#xff0c;具体的步骤可能会因 CNI 插件的类型和你的特定环境而略有不同。设置 Ku…