css选择器的使用

比特踏风人
• 阅读 1770

前言

这周一直在写数据校验,前台单元测试的时候,有时候v层没有渲染出数据,这时就需要手动让他渲染。

it('should create', () => 
    // 如下断言保障了组件在初始化的过程中未发生异常
    expect(component).toBeTruthy();

    // 模拟生产环境后台异步返回数据 
    getTestScheduler().flush();

    // 保障接收模拟数据后,组件重新渲染未发生异常
    fixture.detectChanges();
});

我们可以从潘老师的博客中明白语句的具体含义。但是这还是不够,我们最终确认v层数据渲染了与否还是通过我们肉眼判断的,这就失去了单元测试的意义。为了进一步完善,我们还需要在单元测试中加入断言,断言当前v层成功渲染了数据。

css选择器

要断言当前v层的某一项成功渲染了数据,首先要获取这个v层元素。学习的教程中也有通过table元素和input元素断言的实例。但是我这里获取的是一个div里的值。具体v层代码如下

<div class="row">
  <div class="col-md-2 text-right">
    <label>科目</label>
  </div>
  <div class="col-md-8">
    {{subject.course?.name}}
  </div>
</div>

css选择器的使用

我们想要断言subject.course.name的值。但是这是一个普通的div,没有什么特殊的属性。这时我就想趁此机会了解一下css选择器。
css选择器可以通过多种形式来获取一个v层的元素,介绍几种常用的。
一、绝对定位

const nameInput: HTMLInputElement = fixture.debugElement.query(By.css('html >  
body > div > div > form > input')).nativeElement;

这种定位就是通过一层一层的父子元素关系来找到某一元素,优点是可以准确地找到某一元素。但是,一旦v层相关的元素改变,这里也要跟着变。

二、相对定位
理解了绝对定位,相对定位也就好理解了。

const nameInput: HTMLInputElement = fixture.debugElement.query(By.css('div > table')).nativeElement;

他会匹配所有在某个div下的table元素。

三、属性定位

属性定位又可以分为id定位,class定位和(其他)属性定位。我们在实例中用的就是属性定位。

const nameInput: HTMLInputElement = fixture.debugElement.query(By.css('input[name="name"]')).nativeElement;

expect(nameInput.value).toEqual(student.name);

这里我们就是在匹配一个input元素,且此input的name属性为name。
具体可以看这篇文章:CSS 选择器

使用控制台获得css选择器

我们也可以使用控制台打印某一元素的位置。
css选择器的使用
找到这个元素,右键copy,有copy selector选项,让我们看看打印出来了什么

#root0 > div:nth-child(1) > div.col-md-8

找到了元素位置,剩下的断言就很好写了。
但是也遇到了点问题。

我先用的实例的代码

const subjectCourseNameDiv: HTMLDivElement = fixture.debugElement.query(By.css('#root0 > div:nth-child(1) > div.col-md-8')).nativeElement;

expect(subjectCourseNameDiv.value).toContain('科目名称');

但是断言总是过不去,说我断言的值为undefined。但是对subjectCourseNameDiv进行打印获取到的元素也没有问题。

这时我想到了input与div的不用,我们input是获取的属性的值比如要这样写

<input type="" name="" value="科目名称XXXX">

而div这么写

<div>科目名称XXXX</div>

一个是属性,一个是里面的值。然后去网上查一查div选择器的写法,不应该是subjectCourseNameDiv.value,而是subjectCourseNameDiv.innerText
整体代码如下。

fit('should create', () => {
    expect(component).toBeTruthy();

    const subjectCourseNameDiv: HTMLDivElement = fixture.debugElement.query(By.css('#root0 > div:nth-child(1) > div.col-md-8')).nativeElement;
    expect(subjectCourseNameDiv.innerText).toBe('');

    getTestScheduler().flush();
    fixture.autoDetectChanges();

    expect(subjectCourseNameDiv.innerText).toContain('科目名称');
  });

跑一遍单元测试,成功通过。高兴地提交代码。但是事情没有那么简单。
css选择器的使用
机器人测试过不去,我整体跑一遍单元测试,却在刚刚写的单元测试上报错,说没有找到对应元素。
css选择器的使用

我再单独跑这个单元测试,

css选择器的使用

测试通过。。。

思索一番后,猜测可能由于整体单元测试v层改变,导致找不到元素了。
我们要知道有什么变化。

css选择器的使用

打印一下这个的selector.

#root158 > div

这个数字是158,应该代表测试的接点数。这样我们写的肯定不对,这时我们可以使用相对定位。删除#root0 >.

const subjectCourseNameDiv: HTMLInputElement = fixture.debugElement.query(By.css('div:nth-child(1) > div.col-md-8')).nativeElement;

单元测试通过。

总结

css选择器让我感觉到了html的对象化。原来刚学的时候总以为html与后端语言语法完全不一样。但是其实本质是一样的。这应该就是为什么学一种语言而通全部吧。

点赞
收藏
评论区
推荐文章
blmius blmius
4年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
美凌格栋栋酱 美凌格栋栋酱
7个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
1年前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
4年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
SpringBoot学习:整合shiro自动登录功能(rememberMe记住我功能)
首先在shiro配置类中注入rememberMe管理器!复制代码(https://oscimg.oschina.net/oscnet/675f5689159acfa2c39c91f4df40a00ce0f.gif)/cookie对象;rememberMeCookie()方法是设置Cookie的生成模
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Easter79 Easter79
3年前
SpringBoot学习:整合shiro自动登录功能(rememberMe记住我功能)
首先在shiro配置类中注入rememberMe管理器!复制代码(https://oscimg.oschina.net/oscnet/675f5689159acfa2c39c91f4df40a00ce0f.gif)/cookie对象;rememberMeCookie()方法是设置Cookie的生成模
Stella981 Stella981
3年前
Sass
嵌套规则(NestedRules)Sass允许将一套CSS样式嵌套进另一套样式中,内层的样式将它外层的选择器作为父选择器mainp{color:00ff00;width:97%;.redbox{
Python进阶者 Python进阶者
1年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
比特踏风人
比特踏风人
Lv1
蝴蝶不传千里梦,子规叫断三更月。
文章
2
粉丝
0
获赞
0