Obtén 100% en el cuestionario para continuar
Tipos de datos
Los primitivos (undefined, null, Boolean, Number, String) y los tipos estructurales (Array, Object, Function) con los que se construye toda prueba.
Todo lo que hay en una prueba es un dato. El nombre que escribes en un campo, el código de estado que volvió, la lista de filas de una tabla, la respuesta de sí o no a "¿este botón está visible?".
JavaScript ordena todo eso en una cantidad pequeña de tipos. Aprende los tipos y la mayoría de las sorpresas del lenguaje dejan de ser sorpresas.
Hay dos familias: primitivos y tipos estructurales.
Primitivos
Un primitivo es un valor único y simple. Hay cinco que vas a usar todo el tiempo.
String
Texto. Se escribe entre comillas simples, comillas dobles o backticks.
console.log('Acme Corporation')
console.log("Acme Corporation")Elige un estilo de comillas y mantente consistente. Este curso usa comillas simples.
Number
Cualquier número. JavaScript no separa los números enteros de los decimales: 42 y 3.14 son ambos simplemente Number.
console.log(200)
console.log(19.99)👨🏫 Por eso un código de estado y un precio son del mismo tipo. También significa que0.1 + 0.2te da0.30000000000000004, que no es un bug de JavaScript sino la forma en que las computadoras guardan decimales en todas partes. Nunca hagas aserciones sobre el resultado exacto de una cuenta con decimales.
Boolean
Exactamente dos valores posibles: true y false. Este es el tipo que en el fondo produce toda aserción.
console.log(true)
console.log(false)undefined
El valor de algo que existe pero al que nunca se le dio un valor. JavaScript te lo asigna solo.
let statusCode
console.log(statusCode)Eso imprime undefined. Nadie le asignó nada.
null
El valor de algo definido deliberadamente como "nada". La diferencia con undefined importa: undefined significa "nadie llenó esto", null significa "alguien llenó esto con nada".
const middleName = null
console.log(middleName)👨🏫 En una respuesta de API,"phone": nullsignifica que el campo existe y que el cliente no tiene teléfono. Una clavephoneque falta te daundefined, lo que significa que la API no envió el campo en absoluto. Esos son dos bugs distintos, así que vale la pena poder distinguirlos.
Tipos estructurales
Un tipo estructural guarda varios valores, en una estructura. Hay tres que necesitas.
Array
Una lista ordenada. Se escribe con corchetes y los ítems separados por comas. El orden se preserva, y las posiciones se numeran desde cero.
const sizes = ['Small', 'Medium', 'Large']
console.log(sizes[0])
console.log(sizes[2])
console.log(sizes.length)Eso imprime Small, después Large, después 3.
👨🏫 Contar desde cero confunde a todo el mundo al principio. El primer ítem está en el índice0, así que el último ítem de un array de tres ítems está en el índice2, nunca en el3. Pedirsizes[3]te daundefined.
Un array puede guardar cualquier cosa, incluidos otros arrays y objetos. En pruebas, un array suele ser una lista de filas, una lista de entradas o una lista de valores esperados.
Object
Una colección de valores con nombre. Se escribe con llaves, como pares clave: valor.
const customer = {
name: 'Acme Corporation',
size: 'Large',
active: true,
}
console.log(customer.name)
console.log(customer.active)Eso imprime Acme Corporation, después true.
Un objeto es lo que parece el cuerpo de una respuesta de API, y lo que parece un dato de prueba. Los arrays y los objetos se anidan libremente unos dentro de otros: un array de objetos de cliente es la forma más común que te vas a encontrar.
const customers = [
{ name: 'Acme Corporation', size: 'Large' },
{ name: 'Globex', size: 'Small' },
]
console.log(customers[1].name)Eso imprime Globex.
Function
Un bloque de código reutilizable. En JavaScript una función es un valor como cualquier otro, y por eso pertenece a esta lista y no a un capítulo aparte.
function greet(name) {
return 'Hola, ' + name
}
console.log(greet('Walmyr'))Eso imprime Hola, Walmyr.
👨🏫 El hecho de que una función sea un valor es la idea más importante de este curso. Es lo que te permite pasarle una función alit(), albeforeEach()y alforEach(). La lección 7 cubre las funciones como corresponde.
Cómo verificar un tipo
typeof te dice de qué tipo es un valor.
console.log(typeof 'Acme')
console.log(typeof 42)
console.log(typeof true)
console.log(typeof undefined)
console.log(typeof { name: 'Acme' })
console.log(typeof [1, 2, 3])
console.log(typeof null)Vale la pena quedarse mirando los dos últimos. typeof [1, 2, 3] dice 'object', no 'array', y typeof null también dice 'object', que es un error famoso del lenguaje que nunca se puede arreglar sin romper la web.
Para verificar si algo es un array, usa Array.isArray().
console.log(Array.isArray([1, 2, 3]))
console.log(Array.isArray({ name: 'Acme' }))Eso imprime true, después false.
Resumen de sintaxis 📖
typeof
Devuelve una string con el nombre del tipo de un valor.
typeof 'Acme'Array.isArray()
Devuelve true cuando el valor es un array. La forma confiable de verificarlo, ya que typeof no puede.
Array.isArray(['Small', 'Large']).length
La cantidad de ítems de un array, o la cantidad de caracteres de una string.
['a', 'b', 'c'].length
'Acme'.lengthAcceder a valores
Corchetes y un número para los arrays, un punto y un nombre para los objetos.
sizes[0]
customer.nameLa parte de pruebas 🧪
Los tipos no son algo académico. Aquí está el falso positivo más común de la automatización de pruebas web, y es un problema de tipos.
El texto leído de una página web siempre es un String, incluso cuando parece un número.
it('muestra el total correcto', () => {
cy.get('[data-testid="total"]').invoke('text').then((total) => {
// total es la string '42', no el número 42
expect(Number(total)).to.equal(42)
})
})Sin esa conversión con Number(), comparar '42' con 42 de forma estricta falla, y compararlos de forma laxa pasa por razones que no pretendías. La lección 4 cubre exactamente esa diferencia.
El segundo lugar donde los tipos importan es en las pruebas de API, donde conocer el tipo esperado es la prueba.
it('devuelve un cliente bien formado', async ({ request }) => {
const response = await request.get('/api/customers/1')
const customer = await response.json()
expect(typeof customer.name).toBe('string')
expect(typeof customer.active).toBe('boolean')
expect(Array.isArray(customer.contacts)).toBe(true)
})A esa prueba no le importa cómo se llama el cliente. Le importa que name sea texto, que active sea un sí o no, y que contacts sea una lista. Si un cambio en el backend convierte active en la string 'true', todas las verificaciones de la interfaz podrían seguir pasando mientras esta lo detecta de inmediato.
👨🏫 Un campo que cambia de tipo es uno de los bugs más desagradables de encontrar después, porque el valor sigue pareciendo correcto cuando lo imprimes.'true'ytruese imprimen idénticos.
Contenido sugerido 📚
- Tipos de datos y estructuras de datos en JavaScript - MDN
- String - MDN
- Number - MDN
- Boolean - MDN
- null - MDN
- undefined - MDN
- Array - MDN
- Object - MDN
- typeof - MDN
Ejercicio 🎯
Crea 01-data-types.js en tu fork y haz lo siguiente:
- Declara un valor de cada tipo primitivo: una string, un número, un booleano, un
undefinedy unnull - Declara un array con al menos tres strings, e imprime su longitud y su primer ítem
- Declara un objeto que describa a un cliente, con un nombre, un tamaño y si está activo, e imprime dos de sus campos
- Imprime el
typeofde cada uno de tus cinco primitivos - Imprime
Array.isArray()tanto para tu array como para tu objeto
Ejecútalo con node 01-data-types.js, y después haz el commit y envíalo.
🙊 Aquí hay una forma de escribirlo:
const name = 'Acme Corporation'
const employees = 240
const active = true
let notSetYet
const phone = null
const sizes = ['Small', 'Medium', 'Large']
const customer = { name: 'Acme Corporation', size: 'Large', active: true }
console.log(sizes.length)
console.log(sizes[0])
console.log(customer.name, customer.active)
console.log(typeof name, typeof employees, typeof active, typeof notSetYet, typeof phone)
console.log(Array.isArray(sizes), Array.isArray(customer))Dos cosas para notar en la salida.typeof notSetYetimprimeundefinedaunque no se le asignó nada. Eso es JavaScript llenando el hueco, no un error.typeof phoneimprimeobject, nonull. Ese es el error del lenguaje mencionado arriba. Cuando necesites verificar si algo esnull, compáralo directamente en lugar de confiar entypeof.
Muéstrale al mundo lo que aprendiste 🌎
Para mostrarle a tu red profesional lo que aprendiste en esta lección, publica lo siguiente en LinkedIn.
Empecé el curso "JavaScript para QAs" de @Walmyr Lima e Silva Filho en la @Talking About Testing School, y la primera lección ya me explicó un falso positivo que había visto antes: el texto leído de una página siempre es una string, incluso cuando parece un número, así que compararlo con un número no es la verificación que creías haber escrito. #TalkingAboutTesting #TATSchool #JavaScriptForQAs #JavaScript #TestAutomation
👨🏫 No olvides mencionarme en tu publicación. Aquí está mi perfil de LinkedIn.
Cuestionario
¿Qué devuelve `typeof [1, 2, 3]`, y qué deberías usar en su lugar?
Obtén 100% en el cuestionario para continuar