def Prepare(self,
                app_under_test=None,
                test_bundle=None,
                xctestrun_file_path=None,
                test_type=None,
                signing_options=None):
        """Prepares the test session.

    If xctestrun_file is not provided, will use app under test and test bundle
    path to generate a new xctest file.

    Args:
      app_under_test: string, the path of the application to be tested. It can
          be .ipa or .app.
      test_bundle: string, the path of the test bundle to be tested. It can
          be .ipa or .xctest.
      xctestrun_file_path: string, the path of the xctestrun file. It is the
          configure file to launch test in Xcode 8+.
      test_type: ios_constants.TestType. The type of test bundle.
      signing_options: dict, the signing app options. See
          ios_constants.SIGNING_OPTIONS_JSON_HELP for details.

    Raises:
      ios_errors.IllegalArgumentError:
          1) the app under test/test bundle does not exist;
          2) the app under test/test bundle's extension is invaild.
    """
        if not signing_options:
            signing_options = {}

        if self._work_dir:
            if not os.path.exists(self._work_dir):
                os.mkdir(self._work_dir)
            self._work_dir = os.path.abspath(self._work_dir)
            self._delete_work_dir = False
        else:
            self._work_dir = tempfile.mkdtemp()
            self._delete_work_dir = True

        if self._output_dir:
            if not os.path.exists(self._output_dir):
                os.mkdir(self._output_dir)
            self._delete_output_dir = False
        else:
            self._output_dir = tempfile.mkdtemp()
            self._delete_output_dir = True

        if xctestrun_file_path:
            self._xctestrun_obj = xctestrun.XctestRun(xctestrun_file_path,
                                                      test_type)
        else:
            if not test_bundle:
                raise ios_errors.IllegalArgumentError(
                    'Without providing xctestrun file, test bundle is required.'
                )
            app_under_test_dir, test_bundle_dir = _PrepareBundles(
                self._work_dir, app_under_test, test_bundle)
            test_type = _FinalizeTestType(
                test_bundle_dir,
                self._sdk,
                app_under_test_dir=app_under_test_dir,
                original_test_type=test_type)

            if test_type not in ios_constants.SUPPORTED_TEST_TYPES:
                raise ios_errors.IllegalArgumentError(
                    'The test type %s is not supported. Supported test types are %s'
                    % (test_type, ios_constants.SUPPORTED_TEST_TYPES))

            if test_type != ios_constants.TestType.LOGIC_TEST:
                xctestrun_factory = xctestrun.XctestRunFactory(
                    app_under_test_dir, test_bundle_dir, self._sdk,
                    self._device_arch, test_type, signing_options,
                    self._work_dir)
                self._xctestrun_obj = xctestrun_factory.GenerateXctestrun()
            else:
                self._logic_test_bundle = test_bundle_dir
        self._prepared = True
  def Prepare(self, app_under_test=None, test_bundle=None,
              xctestrun_file_path=None, test_type=None, signing_options=None):
    """Prepares the test session.

    If xctestrun_file is not provided, will use app under test and test bundle
    path to generate a new xctest file or dummy project.

    Args:
      app_under_test: string, the path of the application to be tested. It can
          be .ipa or .app.
      test_bundle: string, the path of the test bundle to be tested. It can
          be .ipa or .xctest.
      xctestrun_file_path: string, the path of the xctestrun file. It is the
          configure file to launch test in Xcode 8+.
      test_type: ios_constants.TestType. The type of test bundle.
      signing_options: dict, the signing app options. See
          ios_constants.SIGNING_OPTIONS_JSON_HELP for details.

    Raises:
      ios_errors.IllegalArgumentError:
          1) the app under test/test bundle does not exist;
          2) the app under test/test bundle's extension is invaild.
    """
    if not signing_options:
      signing_options = {}

    if self._work_dir:
      if not os.path.exists(self._work_dir):
        os.mkdir(self._work_dir)
      self._work_dir = os.path.abspath(self._work_dir)
      self._delete_work_dir = False
    else:
      self._work_dir = tempfile.mkdtemp()
      self._delete_work_dir = True

    if self._output_dir:
      if not os.path.exists(self._output_dir):
        os.mkdir(self._output_dir)
      self._delete_output_dir = False
    else:
      self._output_dir = tempfile.mkdtemp()
      self._delete_output_dir = True

    if xctestrun_file_path:
      xcode_version_num = xcode_info_util.GetXcodeVersionNumber()
      if xcode_version_num < 800:
        raise ios_errors.IllegalArgumentError(
            'The xctestrun file is only supported in Xcode 8+. But current '
            'Xcode version number is %s' % xcode_version_num)
      self._xctestrun_obj = xctestrun.XctestRun(
          xctestrun_file_path, test_type)
    else:
      if not test_bundle:
        raise ios_errors.IllegalArgumentError(
            'Without providing xctestrun file, test bundle is required.')
      app_under_test_dir, test_bundle_dir = _PrepareBundles(
          self._work_dir, app_under_test, test_bundle)
      test_type = _FinalizeTestType(
          test_bundle_dir, self._sdk, app_under_test_dir=app_under_test_dir,
          original_test_type=test_type)

      # xctestrun can only support in Xcode 8+.
      # Since xctestrun approach is more flexiable to local debug and is easy to
      # support tests_to_run feature. So in Xcode 8+, use xctestrun approach to
      # run XCTest and Logic Test.
      if (test_type in ios_constants.SUPPORTED_TEST_TYPES and
          test_type != ios_constants.TestType.LOGIC_TEST and
          xcode_info_util.GetXcodeVersionNumber() >= 800):
        xctestrun_factory = xctestrun.XctestRunFactory(
            app_under_test_dir, test_bundle_dir, self._sdk, test_type,
            signing_options, self._work_dir)
        self._xctestrun_obj = xctestrun_factory.GenerateXctestrun()
      elif test_type == ios_constants.TestType.XCUITEST:
        raise ios_errors.IllegalArgumentError(
            'Only supports running XCUITest under Xcode 8+. '
            'Current xcode version is %s' %
            xcode_info_util.GetXcodeVersionNumber())
      elif test_type == ios_constants.TestType.XCTEST:
        self._dummy_project_obj = dummy_project.DummyProject(
            app_under_test_dir,
            test_bundle_dir,
            self._sdk,
            ios_constants.TestType.XCTEST,
            self._work_dir,
            keychain_path=signing_options.get('keychain_path') or None)
        self._dummy_project_obj.GenerateDummyProject()
      elif test_type == ios_constants.TestType.LOGIC_TEST:
        self._logic_test_bundle = test_bundle_dir
      else:
        raise ios_errors.IllegalArgumentError(
            'The test type %s is not supported. Supported test types are %s'
            % (test_type, ios_constants.SUPPORTED_TEST_TYPES))
    self._prepared = True