Есть отличная удаленная работа для php+codeception+jenkins+allure+docker спецов. 100% remote! Присоединиться к проекту

Что лучше использовать "int" или "enum (перечисление)" для статусов в автоматизации?

java
Теги: #<Tag:0x00007f7b69f837e8>

(Eugene Moskalenko) #1

Ребята, подскажите плиз, что лучше использовать для статусов во фреймворке для автоматизации - “int” или “enum”?

Дело в том, что enum (перечисление) тяжелее, нежели int статусы. Для Android - это принципиально, но наверное и для автоматизации тоже. Понятное дело, что если статусу надо добавить свойство, тогда правильно юзать только enum, но если нет, то можно и int - быстрее, но код не так понятней…

Вот пример:

    public enum PromocodeStatus {
        WITHOUT_PROMOCODE, WITH_PROMOCODE
    }

    public enum PurchaseOffer {
        DOUBLE_PURCHASE_OFFER, SINGLE_PURCHASE_OFFER
    }
   public PromocodeStatus isUsePromocode() {
        switch (this.usePromocode) {
            case WITHOUT_PROMOCODE:
                return WITHOUT_PROMOCODE;
            case WITH_PROMOCODE:
                return WITH_PROMOCODE;
            default:
                throw new ExceptionInInitializerError("Invalid promocode status..");
        }
    }

    public PurchaseOffer isStatusOffer() {
        switch (this.purchaseStatusOffer) {
            case DOUBLE_PURCHASE_OFFER:
                return DOUBLE_PURCHASE_OFFER;
            case SINGLE_PURCHASE_OFFER:
                return SINGLE_PURCHASE_OFFER;
            default:
                throw new ExceptionInInitializerError("Invalid offer status..");
        }
    }

или вот так:

    public static class PromocodeStatus {
        public static final int WITHOUT_PROMOCODE = 0;
        public static final int WITH_PROMOCODE = 1;
    }
   public int isUsePromocode() {
        switch (this.usePromocode) {
            case PromocodeStatus.WITHOUT_PROMOCODE:
                return PromocodeStatus.WITHOUT_PROMOCODE;
            case PromocodeStatus.WITH_PROMOCODE:
                return PromocodeStatus.WITH_PROMOCODE;
            default:
                throw new ExceptionInInitializerError("Invalid promocode status..");
        }
    }

Спасибо, интересно ваше мнение :slight_smile:


(Evgenii) #2

Когда варианта всего два, проще всего использовать boolean.
if (isUsePromoCode) { } else { }


(Eugene Moskalenko) #3

мне кажется boolean - вообще плохой подход, а вдруг придется добавить третий статус?

раньше сам так использовал, потом инты начал, а потом к enum пришел, enum нравится больше всего


#4

Если о тяжести, для автоматизации, скорее всего, вообще не принципиально, если только не гонять тесты огромным числом потоков.

А вот в логах очень неудобно будет видеть цифры, легче читать строки. В случае enum строковое представление у вас будет автоматически.


(Михаил Братухин) #5

Интересно поглядеть где у вас int и enum могут дать заметную разницу во время исполнения. Там разница в лучшем случае на такты процессора и доли миллисикунды.

Вот по поводу сравнения типов int и enum статья на stackoverflow:
Java: Enum vs. Int


(Eugene Moskalenko) #6

за статью спасибо, я на самом то деле сам думаю, что ниче страшного, прост интересно мнение других автоматизаторов


(Sergey Korol) #7

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

Но применять enum нужно уж точно не в таком виде, как вы показали. Нет абсолютно никакого смысла проверять значение инстанс филда через switch, возвращая найденное в cases значение наружу. Это ровно то же самое, если бы вы написали return usePromocode.

Ну и собственно формат именования методов указывает на то, что тип возвращаемого значения должен быть boolean. В такой ситуации правильней будет написать return usePromocode == WITH_PROMOCODE.


(Eugene Moskalenko) #8

Ну почему? У меня все довольно грамотно сделано, вроде, как мне кажется. Раньше было все как вы говорите, просто у меня очень сложная покупка (которая постоянно меняется), и по дурацки сделана верстка (которую никто не будет менять) и на многих лендингах подобные блоки (из-за “такой себе” верстки xpath очень разный на разных лендингах, где есть покупка). К тому же очень много разных вариантов покупок. Из-за чего я принял решение сделать PurchaseContainer, в нем enum-статусы сделать и swich-case делать грамотные проверки, работает он быстро, код понятный. Все в одном месте, очень читабелен код, легкое переиспользование и гибкое маштабирование, при нововведениях в покупках. Пример (часть) моего PurchaseContainer, дальше уже внизу идут проверки switch-case, getter & setter, конструкторы:

public class PurchaseContainer {

    public enum PromocodeStatus {
        WITHOUT_PROMOCODE, WITH_PROMOCODE
    }

    public enum PurchaseOffer {
        DOUBLE_PURCHASE_OFFER, SINGLE_PURCHASE_OFFER
    }

    public enum PurchaseType {
        IOS("#ios"),
        ANDROID("#android"),
        BLACKBERRY("#blackberry");

        private final String link;

        PurchaseType(final String link) {
            this.link = link;
        }

        public String getLink() {
            return this.link;
        }
    }

    public enum PurchasePeriodPlan {
        ONE_MONTH,
        TWO_MONTHS,
        THREE_MONTHS,
        FIVE_MONTHS,
        SIX_MONTHS,
        TEN_MONTHS,
        TWELVE_MONTHS
    }

    public PurchasePeriodPlan getPurchasePeriodPlan() {
        switch (this.purchasePeriodPlan) {
            case ONE_MONTH:
                return PurchasePeriodPlan.ONE_MONTH;
           case TWO_MONTHS:
                return PurchasePeriodPlan.TWO_MONTHS;
            case THREE_MONTHS:
                return PurchasePeriodPlan.THREE_MONTHS;
            case FIVE_MONTHS:
                return PurchasePeriodPlan.FIVE_MONTHS;
            case SIX_MONTHS:
                return PurchasePeriodPlan.SIX_MONTHS;
            case TEN_MONTHS:
                return PurchasePeriodPlan.TEN_MONTHS;
            case TWELVE_MONTHS:
                return PurchasePeriodPlan.TWELVE_MONTHS;
            default:
                throw new ExceptionInInitializerError("Invalid subscription period plan..");
        }
    }

    public PurchaseData setPurchasePeriodPlan(PurchasePeriodPlan purchasePeriodPlan) {
        this.purchasePeriodPlan = purchasePeriodPlan;
        return this;
    }

собственно уже в тестах я в контейнер сетю необходимые мне данные и покупка происходит в разных местах, по разному типу, периоду, с или без промокода, и прочими другими свойствами.

Мне кажется для тестов очень практично использовать понятные статусы, без true и false, поскольку хочется указать понятные значения, к примеру: DISABLE, ACTIVE, такой же статус можно и переиспользовать множество раз, для разных случаев


(Sergey Korol) #9

А теперь вдумайтесь на секунду, что делает ваш код. Вы свитчите строго ограниченное значение, которое никогда не будет чем-то иным, кроме как одним из значений вашего enum (он у вас даже не параметризован). Далее, вы во всех case возвращаете ровно то же самое, что и проверяете. Зачем?! Это равносильно следующему:

final boolean isPresent = true;

if (isPresent)
    return true;

Т.е. вместо того, чтобы сразу вернуть значение purchasePeriodPlan, вы осуществляете совершенно ненужный lookup по всему enum.

Да и default в принципе никогда не сработает при таком подходе.


(Eugene Moskalenko) #11

Та да шото затупил я жестко, там у меня все равно объект с данными покупки со своими геттерами и сеттерами, достаточно вернуть просто this… :slight_smile:

    public PurchasePeriodPlan getPurchasePeriodPlan() {
        return this.purchasePeriodPlan;
    }

:slight_smile:

На счет:

спасибо, развеяли мои сомнения :slight_smile: Мне тоже кажется, что так читается код значительней лучше.