Можно ли использовать «call (или callonce) read» в правой части оценки if в фоновом режиме?

При попытке проверить некоторые параметры mvn/runner по сравнению с одним вариантом сценария я столкнулся с проблемой с параметром чтения.

Эта работа заключается в том, чтобы позволить тестировщикам определять dataRow (информацию об учетной записи пользователя) во время выполнения и использовать уникальную аутентификацию, специфичную для текущего файла функций. Если тест вызывается из команды runner или mvn, мы не хотим, чтобы каждый файл функций аутентифицировался с одним и тем же пользователем, а используем аутентификацию, вызываемую в процессе инициализации конфигурации.

ПРИМЕЧАНИЕ. В конфигурации есть аналогичный код для выполнения вызовов аутентификации только при наличии dsRow, а затем сохранения этого результата аутентификации в файле для повторного использования всеми функциями, определенными в команде runner или mvn. Эта часть конфигурации работает, как и ожидалось

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

  Background: Authentication PreRequisites 
    * def dataSourceRow = karate.get('karate.dsRow', 1)
    * def dataSourceEnv = karate.get('karate.env', 'dev')
    * callonce read('../../../../service-config.js') { dsRow: '#(dataSourceRow)' , env: '#(dataSourceEnv)' }
    
    * if (skipDomainFlag) {karate.logger.debug('skipDomainFlag is set to true so Domain calls cannot be ran!'); karate.abort(); }
    * callonce read('classpath:adapters/domainsession.feature')

    * configure afterFeature = function(){ karate.call('classpath:adapters/logout.feature'); }

    * url baseUrlDomain + domainPath
    * configure headers = domainHeaders
    * header host = domainHost

При попытке проверить, был ли передан karate.dsRow в операторе if, последующий вызов чтения не работает, как в одной строке.

Вот варианты, которые я пробовал: Я получил следующее для работы, но для этого требуется, чтобы вызов (один раз) находился в отдельной строке, и это не разрешено в последующем операторе if. Это работает при локальном запуске файла функций, но не работает при запуске через опцию mvn/runner.

    * if (!(karate.properties['karate.dsRow'])) domainAuth = read('classpath:adapters/domainsession.feature')
    * callonce domainAuth
...
org.graalvm.polyglot.PolyglotException: ReferenceError: "domainAuth" is not defined

Установка параметра callonce после оценки dsRow приводит к следующему:

    * if (!(karate.properties['karate.dsRow'])) domainAuth = read('classpath:adapters/domainsession.feature')
    * if (!(karate.properties['karate.dsRow'])) karate.callonce('#(domainAuth)')
...
01: if (!(karate.properties['karate.dsRow'])) karate.callonce('#(domainAuth)')
<<<<
org.graalvm.polyglot.PolyglotException: js failed:
>>>>
01: read('#(domainAuth)
<<<<
org.graalvm.polyglot.PolyglotException: SyntaxError: Unnamed:1:19 Missing close quote
read('#(domainAuth)
                   ^

or 


    * if (!(karate.properties['karate.dsRow'])) domainAuth = read('classpath:adapters/domainsession.feature')
    * if (!(karate.properties['karate.dsRow'])) karate.callonce(domainAuth)
...
01: if (!(karate.properties['karate.dsRow'])) karate.callonce(domainAuth)
<<<<
org.graalvm.polyglot.PolyglotException: TypeError: invokeMember (callonce) on com.intuit.karate.core.ScenarioBridge@4af5dcab failed due to: no applicable overload found (overloads: [Method[public java.lang.Object com.intuit.karate.core.ScenarioBridge.callonce(java.lang.String)], Method[public java.lang.Object com.intuit.karate.core.ScenarioBridge.callonce(boolean,java.lang.String)]], arguments: [JavaObject[classpath:adapters/domainsession.feature (com.intuit.karate.core.FeatureCall)] (HostObject)])

Объединение вызовов в одну строку приводит к той же перегруженной ошибке.

01: if (!(karate.properties['karate.dsRow'])) { domainAuth = read('classpath:adapters/domainsession.feature'); karate.callonce(domainAuth) }
<<<<
org.graalvm.polyglot.PolyglotException: TypeError: invokeMember (callonce) on com.intuit.karate.core.ScenarioBridge@3ea98e66 failed due to: no applicable overload found (overloads: [Method[public java.lang.Object com.intuit.karate.core.ScenarioBridge.callonce(java.lang.String)], Method[public java.lang.Object com.intuit.karate.core.ScenarioBridge.callonce(boolean,java.lang.String)]], arguments: [JavaObject[classpath:adapters/domainsession.feature (com.intuit.karate.core.FeatureCall)] (HostObject)])


or 



    * if (!(karate.properties['karate.dsRow'])) { karate.set('domainAuth', karate.read('classpath:adapters/domainsession.feature')); karate.callonce('#(domainAuth)'); }
...
01: if (!(karate.properties['karate.dsRow'])) { karate.set('domainAuth', karate.read('classpath:adapters/domainsession.feature')); karate.callonce('#(domainAuth)'); }
<<<<
org.graalvm.polyglot.PolyglotException: js failed:
>>>>
01: read('#(domainAuth)
<<<<
org.graalvm.polyglot.PolyglotException: SyntaxError: Unnamed:1:19 Missing close quote
read('#(domainAuth)
                   ^

Было бы здорово, если бы опция call(once) read работала в правой части оценки if, аналогично опции с одной строкой, чтобы приспособиться к таким ситуациям. Если это нежелательный подход, какие еще варианты вы видите, которые я мог пропустить?

ОБНОВЛЕНИЕ: пример кода для локального тестирования testUrl.feature

Feature:

Scenario:
    * def testUrl = 'http://www.google.com'

тест.функция

Feature: Test for test call and callonce after a conditional
    Background: Authentication PreRequisites 
        * def testUrl = karate.get('karate.testUrl', 'http://www.bing.com')

        #**** Calls combined for troubleshooting of the call/callonce function after a conditional
        #***** uncomment only 1 of the below statements
        # * if (!(karate.properties['karate.testUrl'])) { karate.set('testUrlFile', karate.read('testUrl.feature')); karate.call('#(testUrlFile)'); }
        # * if (!(karate.properties['karate.testUrl'])) { karate.set('testUrlFile', karate.read('testUrl.feature')); karate.call(testUrlFile); }
        # * if (!(karate.properties['karate.testUrl'])) { karate.set('testUrlFile', karate.read('testUrl.feature')); karate.callonce('#(testUrlFile)'); }
        # * if (!(karate.properties['karate.testUrl'])) { karate.set('testUrlFile', karate.read('testUrl.feature')); karate.callonce(testUrlFile); }

        #**** Calls separated for troubleshooting of the call/callonce function after a conditional
        # * if (!(karate.properties['karate.testUrl'])) { karate.set('testUrlFile', karate.read('testUrl.feature')) } 
        # * if (!(karate.properties['karate.testUrl'])) { karate.log('testUrlFile is ',testUrlFile) } 
            #***** uncomment only 1 of the below statements to accompany the above 2 lines
            # * if (testUrlFile) { karate.call('#(testUrlFile)'); }
            # * if (testUrlFile) { karate.call(testUrlFile); }
            # * if (testUrlFile) { karate.callonce('#(testUrlFile)'); }
            # * if (testUrlFile) { karate.callonce(testUrlFile); }

        * url testUrl

    Scenario:
        Given path '/'
        When method GET
        Then status 200
This works in the run of the feature file locally, but fails when running thru mvn/runner option. - этого быть не должно, поэтому я настаиваю на способе повторения. Я также чувствую, что это слишком сложно, и другим будет очень сложно поддерживать его в долгосрочной перспективе. у вас тоже опечатка здесь: read('#(domainAuth)')
Peter Thomas 04.04.2023 03:31

я буду работать над примером, но это может занять некоторое время, чтобы создать что-то, чем можно поделиться. Что касается опечатки, то я ее не вижу

mike 04.04.2023 16:32

Что касается This works in the run of the feature file locally, but fails when running thru mvn/runner option., это правильно, потому что оператор вызова необходим при локальном запуске для вызова аутентификации. Попытка исключить функцию вызова, как и предыдущую функцию чтения, приводит к ошибкам, показанным в последующих строках.

mike 04.04.2023 16:37

возможно, это не опечатка, но я не могу следить за большим потоком, который вы предоставили. возможно, в переменной domainAuth нет одинарной кавычки, как говорится в последней строке сообщения об ошибке. для меня это тот случай, когда нужен пример, который я могу запустить локально

Peter Thomas 04.04.2023 16:53

позвольте мне предположить - пожалуйста, не делайте этого: karate.callonce('#(domainAuth)') и сделайте это вместо этого: karate.callonce(domainAuth) - см.: github.com/karatelabs/karate#rules-for-embedded-expressions

Peter Thomas 04.04.2023 16:55

это было предпринято, как указано выше * if (!(karate.properties['karate.dsRow'])) karate.callonce(domainAuth) во второй части «Установка параметра callonce после оценки dsRow приводит к следующим» результатам блока кода

mike 04.04.2023 17:49

@PeterThomas. Из добавленного выше примера видно, что функции call и callonce не работают после условных операторов. Пожалуйста, попробуйте и проверьте, прав ли я в этой ошибке, или я делаю что-то не так. Я просто устанавливаю для проверки systemproperty значение false, чтобы вызвать условия без необходимости совершать вызовы через исполнителя команды mvn.

mike 05.04.2023 18:52

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

Peter Thomas 05.04.2023 19:21
it works for me - как это работает в ваших настройках - не могли бы вы поделиться? Не знаете, почему вы не можете запустить приведенный выше пример, поскольку это 2 простых файла функций, в которых вы раскомментируете различные строки в примере, а затем можете увидеть ошибки как для операторов callonce, так и для операторов вызова за условным оператором? Вы используете 1.3.1 с java 8 (извините, это не было указано в посте) или другую версию?
mike 05.04.2023 20:17

добавил ответ с моим примером.

Peter Thomas 05.04.2023 20:23
Стоит ли изучать 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
10
79
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

У меня работает, вот простой пример:

Feature:

Background:
* if (true) karate.callonce('called.feature')

Scenario: first
* print 'first'

Scenario: second
* print 'second'

Выход:

23:52:18.580 [main]  INFO  com.intuit.karate - >> lock acquired, begin callonce: read('called.feature')
23:52:18.586 [main]  INFO  com.intuit.karate - [print] in called 
23:52:18.598 [main]  INFO  com.intuit.karate - << lock released, cached callonce: read('called.feature')
23:52:18.602 [main]  INFO  com.intuit.karate - [print] first 
23:52:18.606 [main]  INFO  com.intuit.karate - [print] second 

Таким образом, когда-то кажется, что вызов работает, если в файл передается действительная строка, но передача переменных не работает, отсюда и моя проблема. Я жестко запрограммировал файл функций в функцию callonce, ` * if (!(karate.properties['karate.testUrl'])) { karate.callonce('testUrl.feature'); }, but this requires all variables set in the called function to not be available as they are within a different scope or have to be assigned to a variable, differently than simply being usable after a * callonce read('classpath:testUrl.feature')` использование. Таким образом, комбинация read и callonce терпит неудачу.

mike 05.04.2023 22:06

Изучив код в ScenarioBridge.java, я обнаружил, что вместо чтения файла я могу просто добавить логическое значение для sharedScope в метод callonce, и это, похоже, решило проблему на данный момент...` * if (!( karate.properties['karate.testUrl'])) { karate.callonce(true, 'testUrl.feature'); }`

mike 05.04.2023 22:18

Хотя ваше решение работает, оно не решило мою проблему. Мне пришлось просмотреть код, чтобы найти обходной путь, поскольку область действия callonce без функции чтения не является общей областью действия, и в этом была вся проблема.

mike 06.04.2023 17:21

@mike Я бы никогда не догадался, что вопрос был связан с общей областью действия, но ладно

Peter Thomas 06.04.2023 18:39

Вопрос был связан с использованием чтения (что делает вызов общей областью) и вызова/вызова после оценки, как указано в заголовке и показано в примере. Извините, что sharedScope не был упомянут, но я нашел это как проблему только при поиске исходного кода карате.

mike 06.04.2023 19:01
Ответ принят как подходящий

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

Текущее рабочее решение

 * if (!(karate.properties['karate.testUrl'])) { karate.callonce(true, 'testUrl.feature'); }
karate.callonce() действительно «недокументирован», потому что мы чувствовали, что это будет стимулировать сложные в обслуживании тесты (как я подозреваю, здесь дело обстоит именно так). Я не рекомендую это, потому что мы на самом деле надеялись удалить его в будущем.
Peter Thomas 06.04.2023 18:43

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