Как зациклить cy.task по результату

Я тестирую CRUD для страницы в своем приложении, где для успешного создания реестра требуется уникальный идентификатор в виде 5-значного числа.

Я хотел бы получить случайный доступный идентификатор этой таблицы для использования в тестах, что может быть достигнуто с помощью следующего запроса sql:

    cy.task(
      'sqlQuery',
      `select count(*) as "count" from clients where client_id = '${
        Math.floor(Math.random() * 90000) + 10000
      }'`
    )

Дело в том, что случайное число, возможно, недоступно для использования в качестве идентификатора, поэтому мне нужно будет зациклить эту же задачу, пока не будет доступно сгенерированное число:

    cy.task(
      'sqlQuery',
      `select count(*) as "count" from clients where client_id = '${
        Math.floor(Math.random() * 90000) + 10000
      }'`
    ).then((result: any) => {
      if (result.rows[0].count === 0) {
        // My code to submit the form with the generated number
        // break the loop
      } else {
        // Repeat all of this (where i'm asking for help)
      }
    })

Если count возвращает 0, это означает, что его не использует реестр, иначе он недоступен.

Я предполагаю, что окончательным решением может быть использование некоторого цикла while, но я обнаружил, что этот способ будет более понятным для всех вас, кто знает, что мне нужно.

Я пробовал некоторые подходы, подобные этому, но просто обнаружил, что невозможно присвоить новое значение переменной внутри блока .then, поэтому кажется, что я сделал бесконечный цикл.

    let available = false
    do {
      cy.task(
        'sqlQuery',
        `select count(*) as "count" from clients client_id = '${
          Math.floor(Math.random() * 90000) + 10000
        }'`
      ).then((result: any) => {
        if (result.rows[0].count === 0) {
          // Code to submit the form with the generated number
          available = true
        }
      })
    } while (available === false)

Вы не можете получить это из значения auto_increment? Что-то вроде SHOW TABLE STATUS LIKE 'clients' или сделайте запрос из information_schema

Ingo Guilherme Both Eyng 02.02.2023 22:13

Да, это может быть решение для одного шага регистрации, но на самом деле, чтобы оптимизировать время, у меня есть 3 файла с таким тестом, работающим одновременно. По отдельности они работают нормально, используя auto_increment , но при параллельном запуске все они будут выполнять регистрацию, получая один и тот же идентификатор, и некоторые из них в конечном итоге завершатся ошибкой позже при регистрации.

Leomelzer 02.02.2023 22:32
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
61
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Спросите SQL, какие идентификаторы присутствуют, и проверьте случайный по ним?

Что-то вроде этого:

cy.task('sqlQuery', 'select client_id from clients')
  .then((result: any) => {
    const ids: string[] = result.rows;

    function getNewId(trys = 0) {
      if (trys > 1000) throw new Error('failed')
      const newId = Math.floor(Math.random() * 90000) + 10000
      if (ids.includes(newId)) {
        return getNewId(++trys)
      }
      return newId
    }

    const newId = getNewId()
    cy.wrap(newId).as('newId')
  })

Обновлять

Изменена на рекурсивную функцию javascript, как я обнаружил при тестировании .should(), она не переоценивается Math.floor(Math.random() * 90000) + 10000


Прошло некоторое время с тех пор, как я делал SQL, но, возможно, этот коррелированный подзапрос более эффективен.

SELECT last + 1 as newId FROM (
  SELECT MAX(id) as last FROM clients
)

Спасибо за Ваш ответ. Ids массив будет содержать все уже используемые IDS, а значит с ними нельзя создавать новые реестры. На самом деле я хочу наоборот, чтобы получить доступный идентификатор. Этого можно было бы добиться с помощью еще одного объявления массива, но я думаю, что это может быть не так эффективно, поскольку идентификатор может содержать до 5 цифр, у вас есть какие-либо идеи по этому поводу?

Leomelzer 02.02.2023 23:17

Хорошо, я увидел в вашем SQL clients client_id = '${random.... Вы можете создать функцию либо с помощью javascript, либо с помощью Cypress .should(). добавлю выше.

Bratt 02.02.2023 23:24

Большое спасибо, это было довольно близко к решению, но оно все еще возвращало недоступные идентификаторы, не уверен, но я думаю, это потому, что идентификаторы в этот момент были не массивом только с фактическими значениями идентификатора, а объектом с именем столбца и значением . Я просто изменил условие, чтобы вместо этого использовать некоторый доступ к значению id, и это решено :), просто я собираюсь улучшить тип позже. еще раз спасибо, было очень полезно.

Leomelzer 03.02.2023 16:33

Вы можете использовать такой запрос, чтобы получить 3 неиспользуемых идентификатора для ваших тестов.

MySQL:

SELECT a.id+1 as 'ids'
  FROM clients a
  WHERE 
    NOT EXISTS (SELECT * FROM clients b WHERE a.id+1 = b.id) AND
    a.id+1 < 100000
  ORDER BY a.id
  LIMIT 3

Оракул 11:

SELECT a.id+1 as ids
  FROM clients a
  WHERE
    NOT EXISTS (SELECT * FROM clients b WHERE a.id+1 = b.id) AND
    a.id+1 < 10000 AND
    rownum <= 3
  ORDER BY a.id;

Оракул 12:

SELECT a.id+1 as ids
  FROM clients a
  WHERE
    NOT EXISTS (SELECT * FROM clients b WHERE a.id+1 = b.id) AND
    a.id+1 < 10000
  ORDER BY a.id
  FETCH FIRST 3 ROWS ONLY;

Это будет искать неиспользуемые идентификаторы, проверяя всегда следующий идентификатор, ограничивая его до 3 строк (вы можете ограничить количество, которое вам нужно) для повышения производительности. И только доступные идентификаторы до 100000 (имеет только 5 цифр)


Например:

У вашего стола есть идентификаторы (1, 3, 5, 6, 7, 9, 10)

Этот запрос проверит, существуют ли идентификаторы (2, 4, 6, 8, 10, 11) в таблице. Если его нет, он вернется. Так что этот пример вернется (2, 4, 8)

Другие вопросы по теме