【App自动化测试】(六)移动端自动化中常用的元素定位方式

news2024/9/25 9:40:08

目录

  • 1. Android/iOS基础知识
    • 1.1 Android基础知识
      • 1.1.1 七大布局
      • 1.1.2 四大组件
      • 1.1.3 常用控件
      • 1.1.4 控件的布局
    • 1.2 iOS基础知识
      • 1.2.1 iOS介绍
      • 1.2.2 布局
      • 1.2.3 开发环境
  • 2.控件定位
    • 2.1 元素定位法
      • 2.1.1 dom结构介绍
      • 2.1.2 定位方式
      • 2.1.3 演示代码
    • 2.2 xpath定位
      • 2.2.1 xpath的层级定位
      • 2.2.2 Xpath语法
        • 2.2.2.1 选取节点
        • 2.2.2.2 谓语
        • 2.2.2.3 选取未知节点
        • 2.2.2.4 选取若干路径
    • 2.3 原生定位——uiautomator定位
      • 2.3.1 使用uiautomator定位的优缺点
      • 2.3.2 uiautomator定位方式
        • 2.3.2.1 单一元素定位
        • 2.2.3.2 组合定位(多属性方式定位)
        • 2.2.3.3 父子关系定位 - childselector
        • 2.2.3.4 兄弟定位-fromParent
        • 2.2.3.5 滑动定位
    • 2.4 CSS Selector
      • 2.4.1 定位方式
        • 2.4.1.1 属性定位
        • 2.4.1.2 类定位
      • 2.4.2 演示代码


前言
本文为在霍格沃兹测试开发学社中学习到的一些技术写出来分享给大家,希望有志同道合的小伙伴可以一起交流技术,一起进步~ 😘

1. Android/iOS基础知识

1.1 Android基础知识

1.1.1 七大布局

在这里插入图片描述

Android 是通过容器的布局属性来管理子控件的位置关系,布局过程就是把界面上的所有空间根据他们的间距的大小摆放在正确的位置。

  1. 线性布局:以线性方式进行布局,横向或者纵向进行布局,使用最对的布局方式
  2. 相对布局:现在确定一个元素的位置,再根据这个位置去确定另一个元素的位置
  3. 帧布局:最底层的布局。先设置layout,然后再在上面进行横向布局或者纵向布局
  4. 绝对布局:根据绝对坐标值进行布局,很少使用,兼容性不太好
  5. 表格布局:把页面的图片文字,以表格的方式进行布局
  6. 网格布局:把页面的图片文字,以网格的方式进行布局
  7. 约束布局:是一个ViewGroup,可以在Api9以上的Android系统使用它,它的出现主要是为了解决布局嵌套过多的问题,以灵活的方式定位和调整小部件

1.1.2 四大组件

  1. activity:与用户交互的可视化界面
  2. service:实现程序后台运行的解决方案
  3. content provider:内容提供者,提供程序所需要的数据
  4. broadcast receiver:广播接收器,监听外部事件的到来(比如来电)

1.1.3 常用控件

  1. TextView:文本控件
  2. EditText:可编辑文本控件
  3. Button:按钮
  4. ImageButton:图片按钮
  5. ToggleButton:开关按钮
  6. ImageView:图片控件
  7. CheckBox:复选框控件
  8. RadioButton:单选框控件

1.1.4 控件的布局

布局是一种可用于放置很多控件的容器,它可以按照一定的规律调整内部控件的位置,从而编写出精美的界面。当然,布局的内部除了放置控件外,也可以放置布局,通过多层布局的嵌套,我们就能完成一些比较复杂的界面。
在这里插入图片描述

1.2 iOS基础知识

1.2.1 iOS介绍

  • 由苹果公司为iPhone开发的操作系统,主要给iPhone、iTouch、iPad使用
  • 原名为iPhoneOS,2010年WWDC大会改名为iOS。

1.2.2 布局

iOS去掉了布局的概念,直接用变量之间的相对关系完成位置的计算。

1.2.3 开发环境

系统:MacOS X

开发工具:Xcode

开发语言:ObjectC

安装文件:.ipa文件/.app文件

注意:

使用Appium测试iOS应用需要使用MacOS操作系统。

2.控件定位

2.1 元素定位法

元素定位,实际上就是定位控件。想要一个脚本同时支持android/iOS两个系统,就得保证元素属性(id,aid,xpath等)一致。

2.1.1 dom结构介绍

dom定义:

  • Document Object Model ,文档对象模型

dom应用定义:

  • 最早应用于html和js的交互。用于表示界面的控件层级,界面的结构化描述,常见的格式为html、xml。核心元素为节点和属性。

Xpath的定义:

  • xml路径语言,用于xml中的节点定位。

Android的层级结构:

  • Android应用的层级结构与html不一样,是一个定制的xml
  • app source类似于dom,表示app的层级,代表了界面里面所有的控件树的结构。
  • 每个控件都有它的属性(resourceid,xpath,aid……),没有css属性。

在这里插入图片描述

iOS与Andriod的dom结构的区别

  • dom属性和节点结构类似。
  • 名字和属性的命名不同(比如:android resourceid,ios name,android content-des,ios accessibility-id)

2.1.2 定位方式

  1. 使用id属性定位
  2. 使用accessibility_id属性定位
  3. 使用xpath定位
  4. 使用classname属性定位(不推荐)

Appium Inspector上的元素属性展示:

在这里插入图片描述

2.1.3 演示代码

from appium import webdriver
from appium.webdriver.common.appiumby import AppiumBy

class TestXueQiu:
    def setup(self):
        # 创建一个字典
        desire_cap = {}
        # 平台
        desire_cap['platform'] = 'Android'
        #手机系统版本
        desire_cap['platformVersion']= '6.0'
        # 设备名
        desire_cap['deviceName'] = '127.0.0.1:7555'
        # app 包名
        desire_cap['appPackage'] = 'com.xueqiu.android'
        # app 页面名
        desire_cap['appActivity'] = '.common.MainActivity'
        desire_cap['noReset'] = 'true'
        #每次测试重置数据
        desire_cap['skipDeviceInitization']= 'true'
        #保证可以正常输入中文
        desire_cap['unicodeKeyBoard'] = 'true'
        desire_cap['resetKeyBoard'] = 'true'
        self.driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", desire_cap)
        self.driver.implicitly_wait(10)

    def teardown(self):
        # 回收session
        self.driver.quit()

    def test_api_demo(self):
        """
        1、打开 雪球 app
        2、点击搜索输入框
        3、像搜索框中输入“阿里巴巴”
        4、在搜索结果中选择“阿里巴巴”,然后进行点击
        5、获取这只上 阿里巴巴的股价,并判断这只股价的价格<200
        6、断言
        :return:
        """
        #定位搜索框并进行点击,使用id进行定位
        self.driver.find_element(AppiumBy.ID,'com.xueqiu.android:id/tv_search').click()
        #搜索框输入“阿里巴巴”,使用id进行定位
        self.driver.find_element(AppiumBy.ID,'com.xueqiu.android:id/search_input_text').send_keys("阿里巴巴")
        #在搜索结果中选择“阿里巴巴”,并且点击;使用Xpath进行定位
        self.driver.find_element(AppiumBy.XPATH,"//*[@resource-id='com.xueqiu.android:id/name' and @text='阿里巴巴']").click()
        #获取当前股价,使用id进行定位
        current_price=float(self.driver.find_element(AppiumBy.ID,'com.xueqiu.android:id/current_price').text)
        # 断言
        assert current_price<200

2.2 xpath定位

当存在无法直接定位的元素,或者通过控件定位无法精准的定位我们想要的元素的时可以使用xapth的层级定位方法来精准定位我们想要的元素。

2.2.1 xpath的层级定位

  • 通过父结点定位子结点
  • 通过子结点定位父结点
  • 通过子结点定位兄弟结点
  • 通过爷爷结点定位孙子结点

2.2.2 Xpath语法

以下示例都根据此xml文档进行演示

<?xml version="1.0" encoding="ISO-8859-1"?>

<bookstore>

<book>
  <title lang="eng">Harry Potter</title>
  <price>29.99</price>
</book>

<book>
  <title lang="eng">Learning XML</title>
  <price>39.95</price>
</book>

</bookstore>

2.2.2.1 选取节点

XPath 使用路径表达式在 XML 文档中选取节点。节点是通过沿着路径或者 step 来选取的。

语法

表达式描述
nodename选取此节点的所有子节点。
/从根节点选取。
//从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。
.选取当前节点。
选取当前节点的父节点。
@选取属性。

示例

路径表达式结果
bookstore选取 bookstore 元素的所有子节点。
/bookstore选取根元素 bookstore。 注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径!
bookstore/book选取属于 bookstore 的子元素的所有 book 元素。
//book选取所有 book 子元素,而不管它们在文档中的位置。
bookstore//book选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置。
//@lang选取名为 lang 的所有属性。

2.2.2.2 谓语

  • 谓语用来查找某个特定的节点或者包含某个指定的值的节点。
  • 谓语被嵌在方括号中。

示例

在下面的表格中,我们列出了带有谓语的一些路径表达式,以及表达式的结果:

路径表达式结果
/bookstore/book[1]选取属于 bookstore 子元素的第一个 book 元素。
/bookstore/book[last()]选取属于 bookstore 子元素的最后一个 book 元素。
/bookstore/book[last()-1]选取属于 bookstore 子元素的倒数第二个 book 元素。
/bookstore/book[position()< 3]选取最前面的两个属于 bookstore 元素的子元素的 book 元素。
//title[@lang]选取所有拥有名为 lang 的属性的 title 元素。
//title[@lang=‘eng’]选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性。
/bookstore/book[price>35.00]选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00。
/bookstore/book[price>35.00]/title选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00。

2.2.2.3 选取未知节点

语法

XPath 通配符可用来选取未知的 XML 元素。

通配符描述
*匹配任何元素节点。
@*匹配任何属性节点。
node()匹配任何类型的节点。

示例

在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:

路径表达式结果
/bookstore/*选取 bookstore 元素的所有子元素。
//*选取文档中的所有元素。
//title[@*]选取所有带有属性的 title 元素。

2.2.2.4 选取若干路径

语法

通过在路径表达式中使用|运算符,您可以选取若干个路径。

示例

在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:

路径表达式结果
//book/title | //book/price选取 book 元素的所有 title 和 price 元素。
//title | //price选取文档中的所有 title 和 price 元素。
/bookstore/book/title | //price选取属于 bookstore 元素的 book 元素的所有 title 元素,以及文档中所有的 price 元素。

2.3 原生定位——uiautomator定位

官方文档:https://developer.android.google.cn/reference/androidx/test/uiautomator/UiSelector?hl=en#public-methods_1

2.3.1 使用uiautomator定位的优缺点

优点

  • xpath定位速度慢
  • uiautomator是android的工作引擎,速度快

缺点

  • 表达式书写复杂,容易写错,IDE没有提示。

2.3.2 uiautomator定位方式

2.3.2.1 单一元素定位

使用方法

driver.find_element_by_android_uiautomator(表达式).click()

可定位元素

  • 通过resourceid定位:new UiSelector().resourceid("id")
  • 通过classname定位:new UiSelector().className("className")
  • 通过content-desc定位:new UiSelector().description("content-desc属性")
  • 通过文本进行定位:
    • 通过text文本定位语法:new UiSelector().text("text文本")
    • 如果文本较长,可以使用textContains模糊匹配:new UiSelector().textContains("包含text文本")
    • 同样可以使用textStartsWith是以某个文件开头来匹配:new UiSelector().textStartsWith("以text开头的文本")
    • 可以使用正则表达式textMathes匹配:new UiSelector().textMathes("正则表达式")

备注:Appium不支持通过text进行定位的,如果要想通过text进行定位需要借助xpath表达式,但uiautomator可以使用text进行定位。

2.2.3.2 组合定位(多属性方式定位)

可以自由添加多个属性进行定位

例1:id与text属性组合

ind_text ='resourceId("com.baidu.yuedu:ia/ webbooktitle" ).text("小说")'
driver.find_element_by_android_uiautomator(id_text*).*click()

例2:class与text属性组合

class_text='className("android.widget.TextView").text("图书")'
driver.find_element_by_android_uiautomator(class_text).click()

2.2.3.3 父子关系定位 - childselector

有时候不能直接定位某个元素,但是它的父元素很好定位,这时候就先定位父元素,通过父元素找儿子。

示例

 son='resourceId("com.baidu.yuedu:id /rl_tabs".childselector(text("股票")'
 driver.find_element_by_android_uiautomator(son).click()

2.2.3.4 兄弟定位-fromParent

有时候父元素不好定位,但是跟他相邻的兄弟元素很好定位,这时候就可以通过兄弟元素,找到通一父级元素下的子元素

示例

brother = 'resourceId("com.baidu.yuedu:id/lefttitle").fromParent(text("用户"))'
driver.find_element_by_android_uiautomator(brother).click()

2.2.3.5 滑动定位

书写方法

实现滚动查询找元素:

 
'new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(new UiSelector().text("查找的文本".instance(0)));'

示例

from appium import webdriver
from appium.webdriver.common.appiumby import AppiumBy
from selenium.webdriver.support.wait import WebDriverWait


class TestWebView:
    def setup_class(self):
        desired_caps = {}
        desired_caps['platformName'] = 'Android'
        desired_caps['platformVersion'] = '6.0'
        desired_caps['deviceName'] = 'emulator-5554'
        desired_caps['appPackage'] = 'com.example.android.apis'
        desired_caps['appActivity'] = '.ApiDemos'
        desired_caps['noReset'] = 'true'
        desired_caps['chromeOptions']={'w3c':False}
        #设置chromedriver所在路径
        desired_caps['chromedriverExecutableDir']='E:\chromedriver_webview_test'
        #设置显式指定chromedriver和webview版本对应关系
        #desired_caps['chromedriverChromeMappingFile']='E:\chromedriver_webview_test\mapping.json'
        #开启chromedriverlog
        desired_caps['showChromedriverLog']=True
        self.driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps)
        # 使用隐式等待
        self.driver.implicitly_wait(10)

    def teardown(self):
        self.driver.quit()

    def test_webview(self):
        self.driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR,"new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(new UiSelector().text(\"Views\").instance(0))").click()
        self.driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR,"new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(new UiSelector().text(\"WebView\").instance(0))").click()
        #打印上下文情况
        #['NATIVE_APP', 'WEBVIEW_com.example.android.apis']
        print(self.driver.contexts)
        #webview组件加载慢的时候不一定会及时出现webview上下文,最好显示等待
        WebDriverWait(self.driver,5).until(lambda driver:len(self.driver.contexts)>1)
        #最好显示指定,在多进程同时有webview的时候,最后一个context不一定是当前app的webview
        self.driver.switch_to.context('WEBVIEW_com.example.android.apis')

        from selenium.webdriver.common.by import By
        self.driver.find_element(By.LINK_TEXT,'Hello World! - 1').click()
        #查看当前所在context
        #WEBVIEW_com.example.android.apis
        print(self.driver.current_context)

2.4 CSS Selector

在 Android的Appium Server 1.19.0版本以后和iOS的Appium Server 1.21.0 版本以后,定位方式增加了 CSS Selector。Css selector 会转化为 Android/iOS 原生定位的定位策略,Android转为Android Uiautomator定位方式,而iOS会转为 class chain 定位方式。

2.4.1 定位方式

2.4.1.1 属性定位

id:

driver.find_element_by_css_selector('#id')

description:

driver.find_element_by_css_selector('*[description="Some description"]')

text:

driver.find_element_by_css_selector('*[text="Some description"]')

2.4.1.2 类定位

  • .android.widget.EditText
  • .android.widget.TextView[description="Some description"]
driver.find_element_by_css_selector('.android.widget.EditText')
driver.find_element_by_css_selector('.android.widget.TextView[description="Some description"]')

2.4.2 演示代码

from appium import webdriver
from appium.webdriver.common.appiumby import AppiumBy

class TestXueQiu:
    def setup(self):
        desired_caps = {}
        desired_caps['platformName'] = 'Android'
        desired_caps['platformVersion'] = '6.0'
        desired_caps['deviceName'] = '127.0.0.1:7555'
        desired_caps['appPackage'] = 'com.xueqiu.android'
        desired_caps['appActivity'] = '.view.WelcomeActivityAlias'
        desired_caps['noReset'] = 'true'
        self.driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps)
        self.driver.implicitly_wait(10)

    def teardown(self):
        self.driver.quit()

        def test_search(self):
        """
         1. 打开【雪球】应用首页
         2. 点击搜索框
         3. 向搜索框输入:alibaba
         4. 判断【阿里巴巴】可见
        """
        # 点击搜索框
        element = self.driver.find_element(AppiumBy.CSS_SELECTOR, "#com\.xueqiu\.android\:id\/tv_search")
        element.click()
        # 向搜索框输入:alibaba
        self.driver.find_element(AppiumBy.CSS_SELECTOR, "#com\.xueqiu\.android\:id\/search_input_text").send_keys("alibaba")
        alibaba_element = self.driver.find_element(AppiumBy.CSS_SELECTOR, "*[text='阿里巴巴']")
        displayed = alibaba_element.get_attribute("displayed")
        print(displayed)
        # 判断【阿里巴巴】可见
        assert displayed == "true" 

注意:匹配公式前每一个符号都要加上转义符"\"


文末说明:
接口测试中我们很容易混淆Session、cookie和token,你知道他们有什么区别吗?

快来跟我一起看,一篇文章让你了解三者的区别。😎
⬇⬇⬇⬇⬇⬇⬇
👍👍👍:接口测试经典面试题:Session、cookie、token有什么区别?

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

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

相关文章

Radis基础命令(Hash类型)对field进行的操作

目录 Hash类型 Hash与String比较 Hash类型的常见命令&#xff08;显而易见&#xff0c;在String命令前加入H就是Hash的命令&#xff09; 1.HSET key field value&#xff1a;添加或修改hash类型key的field的值&#xff08;实操举例&#xff09; 2.HGET key field &#xf…

使用Jtest 2022.2简化严格的Java测试

阅读本文&#xff0c;您可以了解您的开发团队如何利用Parasoft Jtest 2022.2 中包含的先进功能和增强功能来简化 Java 测试。 如果开发人员没有自动化测试流程&#xff0c;Java和JUnit测试对他们来说可能是耗时且具有挑战性的。随着Parasoft Jtest2022.2新版本的发布&#xff…

基于JavaWeb的校园故障报修系统(源码+数据脚本+论文+技术文档)

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。这里根据疫情当下&#xff0c;你想解决的问…

欺诈团伙遇上关联网络,邪不压正

你可能永远都想不到骗子有多狡猾、多专业。 最近&#xff0c;小象看到这样一个案例&#xff1a; 近日&#xff0c;小王接到了一个自称“京东客服”的电话&#xff0c;说她网购的银行卡有一些网贷需要注销。因为个人信息与她的真实情况相符&#xff0c;小王便也相信了。随后在…

力扣225 - 用队列实现栈【C/C++实现】

用队列实现栈~一、题目描述二、思路分析1、结构声明与展开剖析2、入栈【入队思想】3、出栈【出队思想】4、获取栈顶元素【队列末尾】5、逐步算法图解三、整体代码展示&#x1f4bb;C语言代码实现&#x1f4bb;C代码实现【⭐】补充&#xff1a;单队列实现栈四、总结与提炼一、题…

谈谈用户态 TCP 协议实现

导语 TCP 协议是目前名气最大、使用最广泛的传输层网络协议。 TCP 是一个可靠的&#xff08;reliable&#xff09;、面向连接的&#xff08;connection-oriented&#xff09;、基于字节流&#xff08;byte-stream&#xff09;、全双工的&#xff08;full-duplex&#xff09;协…

低代码如何增强团队应用开发能力?

虽然数字化转型长期以来一直是企业的战略目标&#xff0c;但疫情加速了这一进程。企业为确保参与度和业务连续性而推出的第一个也是最直接的数字渠道之一是移动应用程序。 然而&#xff0c;对于大多数组织而言&#xff0c;最大的障碍之一是技术团队没有足够的带宽来创建具有严…

基于springboot+java+vue的健身房课程预约信息网站-计算机毕业设计

运行环境 开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven 项目介绍 本健身网…

从零学习 InfiniBand-network架构(八) —— IB协议中的原子操作

从零学习 InfiniBand-network架构&#xff08;八&#xff09; —— IB协议中的原子操作 &#x1f508;声明&#xff1a; &#x1f603;博主主页&#xff1a;王_嘻嘻的CSDN主页 &#x1f511;未经作者允许&#xff0c;禁止转载 &#x1f6a9;本专题部分内容源于《InfiniBand-net…

Spring入门

一、Spring简介 1、Spring概述 官网地址&#xff1a;https://spring.io/ Spring 是最受欢迎的企业级 Java 应用程序开发框架&#xff0c;数以百万的来自世界各地的开发人员使用Spring 框架来创建性能好、易于测试、可重用的代码。 Spring 框架是一个开源的 Java 平台&#xf…

STM32F407输入捕获应用--PWM 输入模式测量脉冲频率与宽度

STM32F407输入捕获应用--PWM 输入模式测量脉冲频率与宽度一、测量脉宽或者频率二、PWM 输入模式三、软件实现3.1、硬件准备3.2代码3.4 验证输入捕获一般应用在两个方面&#xff0c;一个方面是脉冲跳变沿时间测量&#xff0c;另一方面是 PWM 输入测量。一、测量脉宽或者频率 1.测…

Dockerfile(容器与镜像 自定义nginx tomcat 镜像优化)

Dockerfile精讲一、容器与容器镜像之间的关系二、容器镜像分类三、容器镜像获取的方法四、容器镜像获取方法演示4.1 在DockerHub直接下载4.2 把操作系统中文件系统打包为容器镜像4.2.1 安装一个最化的操作系统4.2.2 把操作系统中文件系统进行打包4.2.3 把打包后文件加载至本地文…

连续信号与系统的频域分析之傅里叶级数

信号的傅里叶级数一、正交函数集二、三角形式傅里叶级数三、指数形式的傅里叶级数1. 定义2. 系数确定3. 典型信号的傅里叶级数4. 周期信号的功率谱在LTI系统的时域分析中&#xff0c;输入信号被分解成冲激信号或阶跃信号的叠加&#xff08;积分&#xff09;&#xff0c;然后利用…

LeetCode刷题2:链表篇

提示&#xff1a;本篇共7道力扣题目供大家食用&#xff0c;时间自行把控~ 算法刷题系列笔记 LeetCode刷题1&#xff1a;数组篇 文章目录算法刷题系列笔记作者有话说一、链表知识1.1 什么是链表?1.2 链表的类型1.3 链表操作二、经典题目2.1 Leetcode203.移除链表元素2.2 Leet…

vue-jest vue3

1. 使用vite搭建测试项目&#xff1a; vue create test-vue-jest 选择单元测试&#xff1a;Unit Testing--->jest 2. 配置 jest.config.js module.exports {transform: {"^.\\.vue$": "vue-jest",},preset: vue/cli-plugin-unit-jest/presets/types…

【关于几个问题的思考】

项目如何部署在服务器上面的 此文章以springboot 项目为例&#xff1a; 1.需要申请一台服务器&#xff0c;安装Linux操作系统 2.在服务器安装jdk ,不需要安装Tomcat&#xff0c;springboot 项目内嵌 Tomcat&#xff1b;安装项目的依赖项&#xff1a;如mysql redis等 3.此处利用…

Oracle SQL执行计划操作(9)——位图相关操作

​​​​​​9. 位图相关操作 该类操作基于位图数据(例如:位图索引的位图数据)进行位操作,或将其他结构数据转成位图数据以利用位操作。根据不同的具体SQL语句及其他相关因素,如下各操作可能会出现于相关SQL语句的执行计划。 1)BITMAP AND 对两个位图索引进行“与”(…

【CLS数据淘金第四期】网络流日志-云联网日志分析

导语 云联网&#xff08;Cloud Connect Network&#xff0c;CCN&#xff09;云联网覆盖全球 20 地域&#xff0c;提供云上私有网络间&#xff08;VPC&#xff09;、VPC 与本地数据中心间&#xff08;IDC&#xff09;内网互联的服务&#xff0c;具备全网多点互联、路由自学习、…

Hypermesh三维网格划分技能,以汽车发动机连杆结构为例

作者&#xff1a;米条老师&#xff0c;仿真秀专栏作者 Hypermesh三维单元的划分功能还是非常的丰富和灵活的&#xff0c;通常掌握主要的几个命令基本就能够满足大部分的网格划分工作。首先我们先了解一下在hypermesh中实现三维网格划分的基本步骤&#xff1a; 几何部件分组及…

finereport开发者需要关注的问题

版本问题 如果使用高版本开发&#xff0c;则无法在低版本的设计使用与发布, 所以第一件事情就是要把设计器的版本弄好。 请使用v10.0.0(本地版本需要与当前的中台版本一致)&#xff0c;目前官方已没有直接下载到v10.0.0完整包的地址了&#xff0c;例如&#xff1a;下图为当前的…