Menu

#32 Ability to unfilter components in DefaultComponentFinder

Next Release
closed
Framework (21)
5
2004-01-07
2003-09-22
No

With the functionality of filterComponent and
ignoreComponent methods, it would be nice to be able to
unfilter and unignore components (a single component
and/or all filtered components).

This is mainly helpful because ComponentTester.runBare
calls getTester().ignoreExistingComponents on its own.
I have a top-level frame that is created and displayed
statically (for testing), and is thus filtered by this
call. It would be nice to be able to access the list
of filtered components and remove some/all of the
filtered components at will.

Discussion

  • Timothy Wall

    Timothy Wall - 2003-09-23

    Logged In: YES
    user_id=54098

    Could you describe in a little more detail what the top level frame
    does? Is it part of your application and tests? Or is it part of a
    test fixture? Or something else? It sounds like you want this
    frame to be reachable but not be considered part of your
    application.

    There is already method on ComponentFinder to disable the filter,
    in case you want to see all components currently existing.

    Are you running script-level or code-level tests?

     
  • Timothy Wall

    Timothy Wall - 2003-09-23
    • status: open --> pending
     
  • Mike Dearman

    Mike Dearman - 2003-09-23
    • status: pending --> open
     
  • Mike Dearman

    Mike Dearman - 2003-09-23

    Logged In: YES
    user_id=695583

    The top-level frame is my application derived from JFrame.
    I create it in a static member inside the
    ComponentTestFixture (since creating it in the class
    constructor leads to the application being initialized 1x
    per test function for some reason). Besides, my application
    takes a little while to load, so loading the app once per
    test becomes very time-consuming.

    I use the static member variable to gain access to my
    application, or can use the finder to find the frame. Then
    I can drill down into the heirarchy to find my other UI
    components like the menubar and toolbars.

    I ended up disabling the filtering to solve my problem, but
    I was hoping for a finer-grained level of filtering by
    allowing certain components to be unfiltered.

    I am running code-level tests. I can't seem to get the Test
    Script Editor to work properly to display the application UI
    due to what seems a threading problem - a button or two may
    show up, but both my app and the editor seem to stop
    refreshing even though I can move the mouse over menu
    components to "kickstart" them into redisplaying.

    Another nice feature of filtering or probably more
    appropriately component searching would to be able to
    specify where a component search should start from. I see
    there is a ComponentReference.findInHeirarchy private method
    that has an ancestor parameter, but this is inaccessible to
    external users. This way if we know where to start looking,
    it reduces search costs. Am I missing an obvious way of
    handing this behavior?

     
  • Timothy Wall

    Timothy Wall - 2003-09-23

    Logged In: YES
    user_id=54098

    1) I'm working on an architecture for application fixtures (where
    you can identify the required fixture for a test so that the test can
    either use the existing one or create the fixture if it's missing).
    However, this is mostly intended for scripts so I haven't given
    much thought to using it from code-level tests.
    You might consider modifying ComponentTestFixture to be
    MyAppTestFixture, where you launch the app if necessary or leave
    it alone if not.

    2) When the StepRunner ignores existing components, that should
    really be done by whatever test runner is in use, rather than the
    test itself. The reason it does that is to avoid disposing of things
    like the JUnit Swing test runner, or the Costello editor.
    Unfortunately, there's no design pattern that applies to this
    situation very well.

     
  • Mike Dearman

    Mike Dearman - 2003-09-30

    Logged In: YES
    user_id=695583

    As to (1), that would be very helpful. The only thing to
    watch out for which is biting me right now is if in test 1,
    the application frame is created, test is run, then runBare
    disposes of all windows. This only flags the frame for
    finalization. So in test2, I create another application
    frame, and go looking for it (or some component within it).
    However Frame.getFrames still returns both frames from test
    1 and 2 since the finalize() on Frame may was not called yet
    - so the frame list was not updated.

    As for (2), why do design patterns need to be involved with
    what I'm considering. If a method called
    unfilterComponent(Component comp) is created that will just
    remove the specified component from the filtered list, won't
    that accomplish the needed functionality? And this still
    allows filtering JUnit test runners since it wouldnt return
    disabling filtering components.

     
  • Timothy Wall

    Timothy Wall - 2003-10-01

    Logged In: YES
    user_id=54098

    This is a problem when running multiple tests when your System
    Under Test (SUT) depends on static information in the JVM. You
    have two alternatives:
    1) ensure the test fixture sets up your application once and
    restores it to a usable state after each test run
    2) rearchitect so that you don't depend on Frame.getFrames, and
    use a new class loader for each test to ensure you start with a
    clean slate each time

    I'd recommend 2, unless your SUT has significant setup overhead.
    If you absolutely *must* rely on Frame.getFrames in your tests,
    can you restrict your actions to only those frames that are visible,
    or perhaps only those that match a particular class (this will work
    if you are using a test fixture class loader and your Frame classes
    are loaded by that class loader).

     
  • Mike Dearman

    Mike Dearman - 2003-10-01

    Logged In: YES
    user_id=695583

    As for 2, I don't call Frame.getFrames directly. Abbot
    does. In test 2 (anything but first test), when the
    ComponentReference goes searching via findComponent (and
    thus eventually findMatchesInHierarchy), it calls
    finder.getRootWindows() which calls tracker.getRootWindows()
    which ends up calling Frame.getFrames().

    So until the old frame is finalized (which running
    System.runFinalizer doesnt help), Abbot finds more than one
    frame and more than one of each component within the frames
    I'm searching for in the second+ tests. When all I want is
    the new frame.

    That is why I suggested elsewhere to add a feature to
    specify in ComponentReference a window, component or
    container that the reference is contained within. Not only
    would this speed up searches, but it would fix this problem
    of finding multiple instances of the application top-level
    frame, since I can specify to start searching at the proper
    application frame.

    Or does this functionality exist in some form, and I'm just
    missing it?

     
  • Timothy Wall

    Timothy Wall - 2003-10-01

    Logged In: YES
    user_id=54098

    Indeed, the functionality you mention *does* exist. As of 0.10.0,
    all component references include a reference to the parent
    window. No reference will match a filtered component.

    If a filtered component/window is encountered when searching the
    hierarchy for a match, the search skips that component and
    continues to the next. So your original frame will be ignored if it
    has been filtered.

    If you're writing tests within a ComponentTestFixture and your
    classes under test reference static members, those static
    members will persist across test invocations. You can avoid this
    by setup/teardown of the static bits, using a class loader per test,
    or avoiding the use of static members.

     
  • Timothy Wall

    Timothy Wall - 2004-01-07
    • status: open --> closed