Site Testing

Certified Senior Developer

An often occuring frustration when testing out an interface is that it will work fine within the interface editor, but once we throw it on a site, something goes wrong. That wouldn't be too big a deal as it's all part of development, but whenever we test interfaces on a site, there is no way to see what values the variables are getting for diagnostic purposes. We can hide/show the components on the site, but is there some way for developers to also see variable values? 

  Discussion posts and replies are publicly visible

  • A Site is just a "container" that allows you to expose Interfaces (whether as native UIs or Start forms on process models). The UIs should be fully testable as stand0-alone objects. What sorts of errors are you encountering?

  • 0
    Certified Senior Developer
    in reply to Stewart Burchell

    all sorts, but usually the issue is the data that comes in when testing through a site is different than the data we get when testing through the editor. Unfortunately since we can't see that data, it makes troubleshooting troublesome. 

  • 0
    Appian Employee
    in reply to Marco

    Sounds to me like there's 2 things to attend to here:

    1. when you get issues in the Site you can just navigate to the relevant UI object where the error is actually being thrown and reproduce it
    2. if it's data-related then you may need to pay more attention to the data integrity i.e. where the data is actually being authored to ensure it's correct
  • I will put variable values into text or paragraph fields for debugging.  Specifically, I use a rule!DEBUG() interface that internally shows a red a!boxLayout with the passed ri!label and ri!value from the primary interface.  I have these set to show only in lower environments, and only to system administrators.  Works great, you can even leave the code in up to production.  rule!isDev() and rule!isTest() check an environmental constant cons!SERVER, which holds DEV, TEST or PROD depending on the server.  rule!isDev() returns true for cons!SERVER="DEV", etc.

    On occasion for trickier debugging I'll put a section in that will show for system admins up to production, users report an issue, I can view their task with my debugging info right on the screen, which they cannot see.

    Something like:

    a!boxLayout(
      label: "DEBUG",
      style: "ERROR",
      showWhen: and(
        fn!isusersystemadministrator(loggedInUser()),
        or(
          rule!isDev(),
          rule!isTest()
        )
      ),
      contents: {
        a!paragraphField(
          label: ri!label,
          value: ri!value,
          readOnly: true
        )
      }
    )

  • 0
    Certified Senior Developer
    in reply to Chris

    That's actually a pretty good idea, thanks

  • 0
    Certified Senior Developer
    in reply to Stewart Burchell

    1) I do navigate to the relevant ui object, the problem is I don't know what data the object is getting because opening the object just gives me the test data, not whatever the site is throwing at me. 

    2) Yes, but there could be dozens of variables and/or sources of data and narrowing them down without seeing what data I'm getting in the site is burdensome. 

  • 0
    Certified Lead Developer

    I assume you might have some variables / queries that depend on the user viewing the form.  A technique I've developed gradually is, instead of throwing the loggedInUser() function all over your interface(s), is to capture it only once into a local variable and then using that in queries, group membership checks, etc.  For debugging purposes, this is a big help because then we can instead temporarily change the "local!currentUser" variable delcaration to refer manually to a username instead of loggedInUser(), and make sure things still work.

  • 0
    Certified Lead Developer
    in reply to Marco

    The top level interface in a site page will never get any data passed to rule inputs. Loading that interface into the editor should give you full debugging capabilities.

  • I assume you might have some variables / queries that depend on the user viewing the form.  A technique I've developed gradually is, instead of throwing the loggedInUser() function all over your interface(s), is to capture it only once into a local variable and then using that in queries, group membership checks, etc.  For debugging purposes, this is a big help because then we can instead temporarily change the "local!currentUser" variable delcaration to refer manually to a username instead of loggedInUser(), and make sure things still work.

    100% agree, aside from my debugging hide/show, always always have a local!user: loggedinuser() type variable declared at the top of the interface, and reference local!user throughout (passing to child interfaces as well).  Being able to change this to a value in one line for debugging such as local!user: touser("john.doe"), and test, is huge. 

    My case for loggedinuser() within the debugging only section is so I can throw it on other developers' interfaces that do not have local!user declared for whatever reason.

  • 0
    Appian Employee
    in reply to Marco

    I'm still confused as to why you think the data used in a Site context is any different from the User Interface that is added to that Site? The top-level UI in a Site cannot have any rule inputs (there's nowhere to pass values to it from the containing Site). So: the top-level UI must be self-sufficient. So if you open it up in the Site or as the UI its behaviour will be identical.

    Whilst I understand the thrust of adding "debug" to the front-end (which I view as an unnecessary overhead), the whole rationale for having a toolkit like the Appian Designer is to ensure each object is completely and exhaustively tested before it is ever integrated with another object. In the same environment the behaviour of a UI should be identical whether stand-alone or contained in a Site (the only possible difference might be driven by the role of the User doing the testing i.e. difference between a System Admin account and a a Basic user account).