biocomp / hubitat_ci

Unit testing framework for Hubitat scripts
Apache License 2.0
9 stars 5 forks source link

Two additional FixtureFactories #51

Closed joelwetzel closed 7 months ago

joelwetzel commented 7 months ago

This PR adds two additional FixtureFactories for generating mock devices:

joelwetzel commented 7 months ago

Hey, I wanted to give kudos on your framework. With these new fixtureFactories and the toDateTime (in the other PR), I was just able to write some very readable tests, and found/fixed some bugs in one of my apps.

I have an app called Auto-Shades. It uses a light sensor to automatically control a window shade, depending on the brightness at the window. It also depends on time. For example, if you manually override it, it's supposed to not fight back against you. I've known there were some edge case bugs (because it didn't always behave as I predicted), but since it took a lot of time to test it on real devices, I was never able to track the bugs down. Got them fixed now!

Anyway, I wanted to show you what the test cases can look like:

void "Shade should auto-close when it gets bright"() {
        given: "It's dark outside"
        shadeFixture.initialize(appExecutor, [windowShade: "open"])
        lightSensorFixture.initialize(appExecutor, [illuminance: 200])

        when: "The sun comes out"
        lightSensorFixture.setIlluminance(600)

        then: "The shade should auto-close"
        shadeFixture.state.windowShade == "closed"
        shadeFixture.state.position == 0
    }

void "Shade should not auto-close too soon after a manual open"() {
        given: "It's dark outside and the shades are open"
        shadeFixture.initialize(appExecutor, [windowShade: "open"])
        lightSensorFixture.initialize(appExecutor, [illuminance: 200])

        when: "A few minutes pass and the user manually closes the shade"
        appScript.addMinutes(5)
        shadeFixture.close()

        and: "Twenty minutes pass and it's still dark outside"
        appScript.addMinutes(20)
        lightSensorFixture.setIlluminance(200)

        then: "The shade should not auto-open"
        shadeFixture.state.windowShade == "closed"
        shadeFixture.state.position == 0
    }

    void "Shade can auto-open after a manual close, if enough time has passed"() {
        given: "It's dark outside and the shades are open"
        shadeFixture.initialize(appExecutor, [windowShade: "open"])
        lightSensorFixture.initialize(appExecutor, [illuminance: 200])

        when: "A few minutes pass and the user manually closes the shade"
        appScript.addMinutes(5)
        shadeFixture.close()

        and: "Two hours pass and it's still dark outside"
        appScript.addMinutes(121)
        lightSensorFixture.setIlluminance(200)

        then: "The shade should auto-open"
        shadeFixture.state.windowShade == "open"
        shadeFixture.state.position == 100
    }
biocomp commented 7 months ago

Hey, I wanted to give kudos on your framework. With these new fixtureFactories and the toDateTime (in the other PR), I was just able to write some very readable tests, and found/fixed some bugs in one of my apps.

Thanks for sharing this, I'm really glad this is helpful to someone!

joelwetzel commented 7 months ago

Maybe add the factories to hubitat_ci_example examples and docs?

I'll do that in a future update, once I have more factories done and the design has stabilized.

joelwetzel commented 7 months ago

I think we're ready to merge. Thanks!